一尘不染

NetworkStream.Read挂起/阻止的原因有哪些?

c#

MSDN文档似乎建议NetworkStream.Read将始终立即返回。如果没有找到数据,则返回0。但是,我当前部署了一些代码,仅在某些情况下(而且我还没有弄清楚哪些代码),NetworkStream.Read似乎挂起了。这是我能够从转储文件中收集的堆栈跟踪

00000000705ae850 000007fef784f60d DomainBoundILStubClass.IL_STUB(IntPtr,Byte *,Int32,System.Net.Sockets.SocketFlags)
00000000705ae930 000007fef785c930 System.Net.Sockets.Socket.Receive(Byte [],Int32,Int32,System.Net.Sockets.SocketFlags,System.Net.Sockets.SocketError ByRef)
00000000705ae9b0 000007ff004eb668 System.Net.Sockets.NetworkStream.Read(Byte [],Int32,Int32)
00000000705aea40 000007fef784e6ae MySocketStuff.SocketConnectCallback(System.IAsyncResult)
00000000705aeb20 000007fef84f2bbb System.Net.LazyAsyncResult.Complete(IntPtr)
00000000705aeb90 000007fef7853c7b System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object)
00000000705aebe0 000007fef784e5d3 System.Net.ContextAwareResult.Complete(IntPtr)
00000000705aec40 000007fef7d027f9 System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object,IntPtr)
00000000705aeca0 000007fef8b9815e System.Net.Sockets.Socket.ConnectCallback()
00000000705aed20 000007fef93e14c2 System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(System.Object,Boolean)

我注意到NetworkStrea.Read实际上调用了Socket.Receive,据我所知它可能会阻塞。我只是不知道为什么有时会阻塞而有时却不会。


阅读 631

收藏
2020-05-19

共1个答案

一尘不染

NetworkStream.Read文档的“ 备注”
部分具有误导性。它说:

此方法将数据读入buffer参数,并返回成功读取的字节数。 如果没有可用的数据读取,则Read方法将返回0。Read
操作将读取尽可能多的数据,直到size参数指定的字节数为止。如果远程主机关闭连接,并且已收到所有可用数据,则Read方法立即完成并返回零字节。

应该说:

此方法将数据读入buffer参数,并返回成功读取的字节数。 如果没有数据可读取,则Read方法将阻塞,直到有数据可用或连接关闭为止。
读取操作将读取尽可能多的数据,直到size参数指定的字节数为止。如果远程主机关闭连接,并且已收到所有可用数据,则Read方法立即完成并返回零字节。

2020-05-19