Почему я не могу использовать WaitHandle из Socket.BeginSend для ожидания завершения операции? - PullRequest
3 голосов
/ 16 октября 2010

Я использовал следующий код для асинхронной отправки данных, но заметил, что использование WaitOne в AsyncWaitHandle, полученном из asyncRes , вообще не ждет.Я проверил MSDN и он говорит, что я должен использовать ManualResetEvent.

...
var asyncRes = _socket.BeginSend(encodedFrame, 0, encodedFrame.Length, SocketFlags.None, sendCallback, _socket);
...
var success = asyncRes.AsyncWaitHandle.WaitOne(_timeout, true);
...


 private void sendCallback(IAsyncResult ar)
 {
     _socket.EndSend(ar);            
 }

MSDN также говорит в IAsyncResult:

AsyncWaitHandle: получает WaitHandle, который используется для ожидания асинхронной операциидля завершения.

Так почему я не могу использовать его для этой цели?

Спасибо.

Ответы [ 3 ]

3 голосов
/ 16 октября 2010

Не уверен, правильно ли я понимаю проблему. Но это нормальное поведение. BeginSend означает «делать это асинхронно, если вам нужно ». Это не обязательно очень часто. Во многих случаях отправка может быть завершена синхронно, поскольку в пуле памяти ядра было достаточно места для хранения байтов. Для этого требуется только очень быстрое копирование из памяти в память, и перекрывающаяся передача ввода-вывода завершается немедленно.

Другим хорошим примером этого является FileStream.BeginWrite (), который выполняет запись в кэш файловой системы. Обычно вам нужно записать больше гигабайта, прежде чем он заполнит кэш и начнет тратить время.

В любом случае, при таких обстоятельствах вызов WaitOne () будет немедленно возвращен и не будет использовать тайм-аут. Раймонд Чен недавно написал об этом в блоге . С точки зрения нативного API, но это то, что здесь используется. Я не думаю, что у вас есть настоящая проблема, просто Windows работает эффективно.

1 голос
/ 16 октября 2010

Потому что ты не должен?

Асинхронное соглашение Begin / End предназначено для использования в паре, этот пример может быть слишком простым, чтобы проиллюстрировать, почему вы хотите сделать это так, но на самом деле вам не нужно делать это так Вы можете сделать это также.

var ar = _socket.BeginSend(encodedFrame, 0, encodedFrame.Length, SocketFlags.None);
//...
_socket.EndSend(ar); // this is a blocking operation

Я не вижу смысла в использовании асинхронного ввода-вывода, если вы все равно блокируете ...

1 голос
/ 16 октября 2010

Установка 2-го параметра в true означает, что вы не хотите ждать. Установите для второго параметра значение false, и вы должны увидеть желаемый результат.

Устанавливая для второго параметра значение true, вы в основном говорите «прервать».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...