2015-06-22 6 views
5

Was passiert, wenn eine synchrone Methode innerhalb eines asynchronen Callbacks aufgerufen wird?Aufruf der Sync-Methode von Async Callback?

Beispiel:

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

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

Eine Verbindung angenommen wird und die Asynchron erhalten Rückruf gestartet wird. Wenn die TCP-Verbindung Daten empfängt, ruft sie den Empfangsrückruf auf.

Wird die Sync-Send-Methode aufgerufen, werden dadurch andere Async-Callbacks verhindert?
Oder sind alle Async-Callbacks unabhängig voneinander?

+0

Welche Klasse verwenden Sie 'BeginReceive 'on? –

+0

@Yuval - Die Klasse, die für Async- und Sync-Aufrufe verwendet wird, ist Socket. – Robert

Antwort

2

Rückrufe sind unabhängig, da sie in den IO-Abschlussarbeitern der Thread-Pools aufgerufen werden. Wenn Sie interessiert sind, können Sie das in source code sehen. Diese Methode ist für die Socket Klasse (die TcpClient und UdpClient Verwendung intern), in dem überlappten IO verwendet wird, um den Rückruf aufrufen (Kommentar oben auf asyncResult.SetUnmanagedStructures Aufruf sehen:

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

Ja, Rückrufe sind unabhängig voneinander. Sie werden im Thread-Pool ausgeführt. Es ist nichts falsch daran, dies zu tun. Mixed Sync und Async IO ist in Ordnung. Sie können Async-E/A dort verwenden, wo Sie den größten Nutzen daraus ziehen (Orte mit hohem Volumen und hohen Wartezeiten).

Vergessen Sie nicht, EndReceive aufzurufen.

Beachten Sie auch, dass das APM-Muster dank await veraltet ist. Wahrscheinlich solltest du wechseln.