2015-06-22 2 views
5

Что происходит, когда синхронный метод вызывается в асинхронном обратном вызове?Вызов метода синхронизации вызова из Async Callback?

Пример:

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

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

соединение принимается и асинхронной получают запускается обратный вызов. Когда tcp-соединение получает данные, он вызывает обратный вызов приема.

Если вызван метод отправки синхронных сообщений, происходит ли остановка других асинхронных обратных вызовов?
Или все асинхронные обратные вызовы независимы друг от друга?

+0

Какой класс вы используете для 'BeginReceive 'on? –

+0

@Yuval - Класс, используемый для вызовов Async и Sync, - Socket. – Robert

ответ

2

Обратные вызовы являются независимыми, поскольку они вызываются в рабочих пусках ввода-вывода потоков.

Если вам интересно, вы можете видеть это в source code. Данный метод предназначен для Socket класса (который TcpClient и UdpClient использование внутренне), где перекрывающихся 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); 
    } 
} 
2

Да, обратные вызовы не зависят друг от друга. Они выполняются в пуле потоков. Нет ничего плохого в этом. Смешанная синхронизация и асинхронный ввод-вывод прекрасны. Вы можете использовать async IO в тех местах, где это дает вам наибольшую выгоду (большие места с большим временем ожидания).

Не забудьте вызвать EndReceive.

Также обратите внимание, что шаблон APM устарел благодаря await. Возможно, вы должны переключиться.

Смежные вопросы