当前位置: 首页 > 编程语言 > C#

NetworkStream.Read()和NetworkStream.BeginRead()的区别?分享

时间:2023-04-10 18:33:33 C#

NetworkStream.Read()和NetworkStream.BeginRead()的区别?我需要从NetworkStream中读取,它随机发送数据并且数据包的大小不断变化。我正在实现一个多线程应用程序,其中每个线程都有自己的流来读取。如果流中没有数据,应用程序应该一直等待数据到达。但是,如果服务器完成发送数据并终止会话,那么它应该退出。本来我使用Read方法从流中获取数据,但是它用于阻塞线程并等待直到数据出现在流中。MSDN上的文档建议,如果没有可供读取的数据,Read方法返回0。如果远程主机关闭连接,并且已接收到所有可用数据,Read方法立即完成并返回零字节。但就我而言,我从未让Read方法返回0并正常退出。它只是无限期地等待。在我的进一步调查中,我遇到了BeginRead,一旦收到数据,BeginRead就会异步调用回调方法。我也尝试过使用这种方法查看各种实现,但是,我无法确定何时使用BeginRead而不是Read会更有利。在我看来,BeginRead的优点是被异步调用,它不会阻塞当前线程。但是在我的应用程序中,我已经有一个单独的线程从流中读取和处理数据,所以这对我来说没什么大不了的。我使用BeginRead,但继续使用WaitHandle阻塞线程:byte[]readBuffer=newbyte[32];varasyncReader=stream.BeginRead(readBuffer,0,readBuffer.Length,null,null);WaitHandlehandle=asyncReader.AsyncWaitHandle;//给读者2秒的时间响应一个值boolcompleted=handle.WaitOne(2000,false);如果(完成){intbytesRead=stream.EndRead(asyncReader);StringBuilder消息=newStringBuilder();message.Append(Encoding.ASCII.GetString(readBuffer,0,bytesRead));基本上,它允许使用WaitHandle超时进行异步读取,给出一个布尔值(已完成)。这是我从我的一个WindowsMobile项目复制并粘贴的完整流阅读代码:privatestaticboolGetResponse(NetworkStreamstream,outstringresponse){byte[]readBuffer=newbyte[32];varasyncReader=stream.BeginRead(readBuffer,0,readBuffer.Length,null,null);WaitHandlehandle=asyncReader.AsyncWaitHandle;//给读者2秒的时间来响应一个值boolcompleted=handle.WaitOne(2000,false);如果(完成){intbytesRead=stream.EndRead(asyncReader);StringBuilder消息=newStringBuilder();message.Append(Encoding.ASCII.GetString(readBuffer,0,bytesRead));if(bytesRead==readBuffer.Length){//可能有超过32个字节要读取,因此获取响应字符串的下一个//部分continuedResponse;if(GetResponse(stream,outcontinuedResponse)){message.Append(continuedResponse);}}响应=message.ToString();返回真;}else{intbytesRead=stream.EndRead(asyncReader);if(bytesRead==0){//返回了0个字节,所以读取h作为完成响应=string.Empty;返回真;}else{thrownewTimeoutException("设备未能在适当的时间内读取。");}}}异步I/O可以用来在更少的线程中实现相同数量的I/O。如您所知,现在您的应用程序每个Stream有一个主题,这适用于少量连接,但是如果您需要一次支持10000个怎么办?对于异步I/O,这不再是必需的,因为读取完成回调允许传递标识相关流的上下文。您的读取不再阻塞,因此您不需要每个流一个线程。无论您使用同步还是异步I/O,都有一种方法可以在相关API的返回码上检测和处理流关闭。如果套接字已经关闭,BeginRead将失败并抛出IOException。Close将在异步读取挂起时触发回调,然后EndRead将告诉您播放状态。当您的应用程序调用BeginRead时,系统会等待直到接收到数据或发生错误,然后系统使用单独的线程执行指定的回调方法并阻塞在EndRead上,直到提供的NetworkStream读取数据或抛出异常。您是否尝试过server.ReceiveTimeout?您可以设置Read()函数在返回零之前等待输入数据的时间。在您的情况下,此属性可能在某处设置为无限。BeginRead是一个异步进程,这意味着您的主线程将在另一个进程中启动Read。所以现在我们有2个并行进程。如果你想要结果,你必须调用EndRead,它会给出结果。somepsudoBeginRead()//...在主对象中做一些事情,同时在另一个线程中获取结果varresult=EndRead();但是如果你的主线程没有别的事可做,你必须要请求结果,你应该调用Read。以上就是C#学习教程:NetworkStream.Read()和NetworkStream.BeginRead()的区别?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: