代码之家  ›  专栏  ›  技术社区  ›  jassuncao

为什么我不能使用Socket.BeginSend中的WaitHandle来等待操作完成?

  •  3
  • jassuncao  · 技术社区  · 15 年前

    我使用下面的代码异步发送数据,但是我注意到在AsyncWaitHandle中使用WaitOne 异步 一点也不等。我检查了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 回复  |  直到 15 年前
        1
  •  3
  •   Hans Passant    15 年前

    不确定我是否正确理解了这个问题。但这是正常的行为。BeginSend的意思是“如果 你必须 ". 不必经常这样。在许多情况下,发送可以同步完成,因为内核内存池中有足够的空间来存储字节。它只需要一个非常快的内存到内存的拷贝,重叠的I/O传输立即完成。

    另一个很好的例子是FileStream.BeginWrite(),它写入文件系统缓存。通常您必须先写入超过1 GB的数据,然后才能填满缓存并开始占用时间。

    blogged about this recently . 从本机API的角度来看,这里使用的就是这个。我不认为你有什么真正的问题,只是Windows的工作效率。

        2
  •  1
  •   John Leidegren    15 年前

    因为你不该这么做?

    Begin/End异步约定是成对使用的,这个示例可能太简单,无法说明为什么要这样做,但事实是,您不需要这样做,也可以这样做。

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

    我不认为使用异步IO的意义,如果你最终还是阻止了。。。

        3
  •  1
  •   Hogan    15 年前

    将第二个参数设置为true表示您不想等待。将第二个参数设置为false,您将看到所需的结果。

    通过将第二个参数设置为true,基本上就是说“abort”。

    推荐文章