Why can't I use the WaitHandle from Socket.BeginSend to wait for the operation to complete?
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 voi开发者_JS百科d 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.
Because you are not supposed to?
The Begin/End async convention is meant to be used in pair, this example might be too simple to illustrate why you would want to do it like this, but the fact is that you don't need to do it like that, you can do this as well.
var ar = _socket.BeginSend(encodedFrame, 0, encodedFrame.Length, SocketFlags.None);
//...
_socket.EndSend(ar); // this is a blocking operation
I don't see the point in using async IO if you end up blocking anyway...
Setting the 2nd param to true is saying you don't want to wait. Set the 2nd param to false and you should see the result you want.
By setting the 2nd param to true you are basically saying "abort".
精彩评论