如何在不关闭流的情况下取消NetworkStream.ReadAsync [英] How to cancel NetworkStream.ReadAsync without closing stream

查看:100
本文介绍了如何在不关闭流的情况下取消NetworkStream.ReadAsync的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用NetworkStream.ReadAsync()读取数据,但是一旦找到,我就找不到如何取消ReadAsync()的方法.作为背景,NetworkStream是由连接的BluetoothClient对象(来自32Feet.NET Bluetooth库)提供给我的.

I am trying to use NetworkStream.ReadAsync() to read data but I cannot find how to cancel the ReadAsync() once called. For background, the NetworkStream is provided to me by a connected BluetoothClient object (from 32Feet.NET Bluetooth Library).

我正在尝试的当前工作代码如下.

The current get-it-working code I'm trying is below.

int bytesRead;

while (this.continueReading)
{
    bytesRead = await this.stream.ReadAsync(this.buffer, 0, (int)this.buffer.Length);

    Console.WriteLine("Received {0} bytes", bytesRead);
}

Console.WriteLine("Receive loop has ended");

该代码可以很好地接收数据,并且如果将continueReading标志设置为false并且已接收到数据,它将停止循环,但是直到接收到数据,它才不会继续通过ReadAsync()行.我看不到如何在不接收数据的情况下中止通话.

The code works fine receiving data, and will stop looping if the continueReading flag is set to false and data is received, but until data is received it will not proceed past the ReadAsync() line. I cannot see how to abort the call without receiving data.

我知道ReadAsync的重载提供了CancellationToken,但似乎由于NetworkStream不会覆盖默认的ReadAsync行为,因此令牌被忽略(请参阅

I am aware that there is an overload of ReadAsync which provides a CancellationToken, but it appears that as NetworkStream doesn't override the default ReadAsync behaviour, the token is ignored (see NetworkStream.ReadAsync with a cancellation token never cancels).

我尝试关闭基础流,这导致等待的ReadAsync调用引发ObjectDisposedException,基础蓝牙连接也被关闭.理想情况下,我不想为了停止阅读而完全切断与设备的连接.这样做似乎不是一种干净的方法,并且感觉不必为了中断va ReadAsync()调用而中断整个流.

I've tried closing the underlying stream, and this causes the waiting ReadAsync call to throw ObjectDisposedException, and the underlying Bluetooth connection gets closed too. Ideally I don't want to completely sever the connection with the device just to stop reading. It doesn't seem a clean way of doing it, and feels unnecessary to tear down the entire stream just to interrupt va ReadAsync() call.

有什么建议吗?

推荐答案

您可以围绕NetworkStream.Read(或ReadAsync)实现一个异步包装器,该包装器还会收到一个取消令牌,您可以对其进行监视和兑现.像这样:

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);
}

请注意,我只是在说明这个想法,您可能不打算考虑返回Task<TResult>,以及是否要进行do {} while循环,任何其他处理或清理等工作-均根据您的需求.

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.

我还要提醒您注意Stephen Toub的文章

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.

这篇关于如何在不关闭流的情况下取消NetworkStream.ReadAsync的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆