5

What happens when a synchronous method is called within an asynchronous callback?

Example:

private void AcceptCallback(IAsyncResult AR)
{
    tcp.BeginReceive(ReceiveCallback);
}

private void ReceiveCallback(IAsyncResult AR)
{
    tcp.Send(data);
}

A connection is accepted and the async receive callback is started. When the tcp connection receives data, it calls the receive callback.

If the sync Send method is called, does that stop other async callbacks from happening?
Or are all async callbacks independent of each other?

2
  • Which class are you using to BeginReceive on? Commented Jun 22, 2015 at 12:51
  • @Yuval - The class being used for Async and Sync calls is Socket. Commented Jun 22, 2015 at 14:29

2 Answers 2

2

Callbacks are independent as they're invoked on the thread-pools IO completion workers.

If you're interested, you can see that in the source code. This particular method is for the Socket class (which TcpClient and UdpClient use internally), where overlapped IO is used to invoke the callback (see the comment on top of asyncResult.SetUnmanagedStructures invocation:

private void DoBeginReceiveFrom(byte[] buffer, int offset, 
                                int size, SocketFlags socketFlags,
                                EndPoint endPointSnapshot, SocketAddress 
                                socketAddress, OverlappedAsyncResult asyncResult)
{
    EndPoint oldEndPoint = m_RightEndPoint;
    SocketError errorCode = SocketError.SocketError;
    try
    {
        // Set up asyncResult for overlapped WSARecvFrom.
        // This call will use completion ports on WinNT and Overlapped IO on Win9x.
        asyncResult.SetUnmanagedStructures(
                buffer, offset, size, 
                socketAddress, true /* pin remoteEP*/, 
                ref Caches.ReceiveOverlappedCache);

        asyncResult.SocketAddressOriginal = endPointSnapshot.Serialize();

        if (m_RightEndPoint == null) 
        {
            m_RightEndPoint = endPointSnapshot;
        }

        int bytesTransferred;
        errorCode = UnsafeNclNativeMethods.OSSOCK.WSARecvFrom(
            m_Handle,
            ref asyncResult.m_SingleBuffer,
            1,
            out bytesTransferred,
            ref socketFlags,
            asyncResult.GetSocketAddressPtr(),
            asyncResult.GetSocketAddressSizePtr(),
            asyncResult.OverlappedHandle,
            IntPtr.Zero );

        if (errorCode!=SocketError.Success)
        {
            errorCode = (SocketError)Marshal.GetLastWin32Error();
        }
    }
    catch (ObjectDisposedException)
    {
        m_RightEndPoint = oldEndPoint;
        throw;
    }
    finally
    {
        errorCode = asyncResult.CheckAsyncCallOverlappedResult(errorCode);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

Yes, callbacks are independent of each other. They execute on the thread pool. There is nothing wrong with doing this. Mixed sync and async IO is fine. You can use async IO in those places where it gives you the greatest benefit (high-volume places with high wait times).

Don't forget to call EndReceive.

Also note, that the APM pattern is obsolete thanks to await. Probably you should switch.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.