簡體   English   中英

從Async Callback調用Sync方法調用?

[英]Call Sync method call from Async Callback?

在異步回調中調用同步方法時會發生什么?

例:

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

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

接受連接並啟動異步接收回調。 當tcp連接接收數據時,它會調用接收回調。

如果調用同步Send方法,是否會阻止其他異步回調發生?
或者所有異步回調都是相互獨立的?

是的,回調是相互獨立的。 它們在線程池上執行。 這樣做沒有錯。 混合同步和異步IO很好。 您可以在可以獲得最大收益的位置使用異步IO(具有較高等待時間的高容量位置)。

別忘了給EndReceive打電話。

另請注意,由於await ,APM模式已過時。 可能你應該切換。

回調是獨立的,因為它們是在線程池IO完成工作程序上調用的。

如果您有興趣,可以在源代碼中看到。 這個特殊方法適用於Socket類( TcpClientUdpClient內部使用),其中重疊IO用於調用回調(請參閱asyncResult.SetUnmanagedStructures調用之上的注釋:

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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM