2015-06-22 32 views
5

Cosa succede quando un metodo sincrono viene chiamato all'interno di un callback asincrono?Chiamata al metodo di sincronizzazione chiamata da richiamata asincrona?

Esempio:

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

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

Una connessione viene accettata e l'async ricezione viene avviato callback. Quando la connessione TCP riceve i dati, chiama la richiamata di ricezione.

Se viene chiamato il metodo di sincronizzazione, interrompe altri richiami asincroni?
Oppure tutte le callback asincrone sono indipendenti l'una dall'altra?

+0

Quale classe stai usando a 'BeginReceive 'on? –

+0

@Yuval - La classe utilizzata per le chiamate Async e Sync è Socket. – Robert

risposta

2

Le richiamate sono indipendenti in quanto vengono invocate sui worker di completamento degli ordini dei pool di thread.

Se sei interessato, puoi vederlo nello source code. Questo particolare metodo è per la classe Socket (che TcpClient e UdpClient uso interno), dove si sovrapponevano IO viene utilizzato per richiamare il callback (si veda il commento in cima asyncResult.SetUnmanagedStructures invocazione:

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

Sì, le richiamate sono indipendenti l'una dall'altra. Eseguono nel pool di thread. Non c'è niente di sbagliato nel farlo. La sincronizzazione mista e l'I/O asincrono vanno bene. È possibile utilizzare l'I/O asincrono in quei luoghi in cui offre il massimo vantaggio (luoghi con volumi elevati con tempi di attesa elevati).

Non dimenticare di chiamare EndReceive.

Si noti inoltre che il pattern APM è obsoleto grazie a await. Probabilmente dovresti cambiare.

Problemi correlati