Why can not I use the Socket.BeginSend WaitHandle to wait for the operation to complete?

advertisements

I was using the following code to send data asynchronously but I noticed that using WaitOne in the AsyncWaitHandle that I get from asyncRes doesn't wait at all. I checked MSDN and it says I should use a 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 also says in IAsyncResult:

AsyncWaitHandle: Gets a WaitHandle that is used to wait for an asynchronous operation to complete.

So why can't I use it for that purpose?

Thank you.


Not sure if I understand the problem correctly. But this is normal behavior. BeginSend means "do this asynchronously if you have to". It doesn't have to very often. In many cases, the send can be completed synchronously because there was enough space in the kernel memory pool to store the bytes. That only needs a very fast memory-to-memory copy and the overlapped I/O transfer completes immediately.

Another good example of this is FileStream.BeginWrite(), that writes to the file system cache. You typically have to write more than a gigabyte before that fills up the cache and starts taking time.

Anyhoo, under these circumstances the WaitOne() call will return immediately and not use the timeout. Raymond Chen just blogged about this recently. From a native API point of view but that's what is being used here. I don't think you've got a real problem here, just Windows working efficiently.