我对使用Async模式进行流读取和写入相对较新,并且想知道这个问题的答案是否如此明显,它是不是明确地写在任何地方:
当调用NetworkStream.BeginRead
时,我传递一个回调参数,根据MSDN执行“BeginRead完成时”。它还说“你的回调方法应该调用EndRead方法。”
然后根据NetworkStream.EndRead
的文档,“方法完成了在BeginRead方法中启动的异步读取操作”。它还提到这种方法“阻止数据可用。”
我知道EndRead方法对于确定接收的字节数也很有用。
我的问题是:
如果在BeginRead回调中调用EndRead方法,它是否真的会阻塞?调用回调时,读操作是否已经完成?
示例代码
byte[] streamBuffer = new byte[1024];
public void SomeFunction()
{
TcpClient client = new TcpClient();
client.Connect(IPAddress.Parse("127.0.0.1"), 32000);
NetworkStream stream = client.GetStream();
stream.BeginRead(streamBuffer,0,streamBuffer.Length,ReadCallback,stream);
}
public void ReadCallback(IAsyncResult ar)
{
NetworkStream stream = ar.AsyncState as NetworkStream;
// Will this call ever actually "block" or will it
// return immediately? Isn't the read operation
// already complete?
int bytesRead = stream.EndRead(ar);
// Other stuff here
}
答案 0 :(得分:1)
您可以在两种情况下使用EndRead:
您也可以在没有回叫功能的情况下使用EndRead:
myStream.BeginRead(...);
//同时做很多工作
//当我的工作完成后,等待流完成其工作
myStream.EndRead(...);
EndRead
将抛出异常。
答案 1 :(得分:1)
当回调触发时,读取操作始终完成。完成是首先触发回调的内容。所以当在回调方法中使用它时,EndRead()永远不会阻塞。
请注意“已完成”也可能意味着“失败”,EndRead()将抛出异常。一个非常常见的异常是ObjectDisposedException,当异步读取正在进行时关闭套接字时抛出。退出程序时,一定要抓住它。
答案 2 :(得分:0)
不,因为EndRead
方法被调用(和阻塞)在中被异步调用的委托。所以是的,EndRead
的方法是阻塞的,但不是在调用BeginRead
的执行线程上。