尽管存在大量缓冲空间,但Socket.BeginSend并未完全同步完成

为什么Socket.BeginSend如此快速地异步,如此不可预测? 我知道它应该是异步的,但它也可以立即完成,在这种情况下, IAsyncResult.CompletedSynchronously设置。 我希望CompletedSynchronously为真,直到8KB发送缓冲区被填满。 下面的测试用例(为简洁而剥离的清理代码)演示了在缓冲仅6个字节的数据之后, BeginSend在(通常)第3次迭代时异步:

 TcpListener listener = new TcpListener(IPAddress.Any, 35001); listener.Start(); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) client.Connect(new IPEndPoint(IPAddress.Loopback, 35001)); Socket server = listener.AcceptSocket()) for (int i = 1; i  sent = true, null); Assert.IsTrue(result.CompletedSynchronously, // fails typ. on 3rd iteration String.Format("Asynchronous on iteration {0}", i)); Assert.IsTrue(sent); client.EndSend(result); } 

异步时的确切迭代有点随机。 当进程开始时,它是3.然后它为所有新套接字的1。 我偶尔会看到其他数字。 我知道有8KB套接字发送缓冲区,因为Socket.SendSocket.Blocking = false )停止在大约8KB。

方法Socket.SendAsync行为类似,但它总是异步完成(即不尝试直接缓冲区写入)。 请参阅我关于Socket.SendAsync的相关问题 。

出于性能原因,我需要BeginSend主要是同步的(异步回调更慢)。 更不用说不可预测性破坏了我的低级通信代码的unit testing和基准测试。