How to cancel NetworkStream.ReadAsync without closing stream

。_饼干妹妹 提交于 2019-12-04 01:12:57

You can implement an async wrapper around NetworkStream.Read (or ReadAsync), which also receives a cancellationtoken that you can monitor and honor yourself. Something like this:

Task MyCancelableNetworkStreamReadAsync(NetworkStream stream, CancellationToken ct)
{
...
if(this.stream.CanRead)
{
  do 
  {
    //check ct.IsCancellationRequested and act as needed
    bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length);
  }
  while(myNetworkStream.DataAvailable);
}

Please note that I am only trying to illustrate the idea and you might wnt to consider returning Task<TResult>, as well as whether to have the do{}while loop, any additional processing or cleanup, etc. - all according to your needs.

I would also point your attention to the article by Stephen Toub How do I cancel non-cancelable async operations? and the WithCancellation extension he creates there.

You cannot cancel the ReadAsync since the internal call is unmanaged and uses IOCompletion ports.. Your options are as follows.

  1. Use Socket.Shutdown(). This will return ReadAsync with a socket error of OperationAborted.
  2. Wait for the read to timeout.
  3. Check if data is available before reading from the socket.

I am managing the cancellation by having the Task wait for the cancellation token call between the async call and the await statement like this:

try {

 ....

 Task<int> readTask = input.ReadAsync(buffer, 0, buffer.Length);
 readTask.Wait(myCancellationToken);
 int readBytes= await readTask;

....

}
catch ( OperationCanceledException e )
{
   // handle cancellation
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!