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

我正在尝试的当前启动代码如下。

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()行。我看不到如何在不接收数据的情况下中止通话。

我知道ReadAsync的重载提供了CancellationToken,但似乎由于NetworkStream不会覆盖默认的ReadAsync行为,因此将忽略该 token (请参阅NetworkStream.ReadAsync with a cancellation token never cancels)。

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

有什么建议吗?

最佳答案

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

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循环,任何其他处理或清理等工作-均根据您的需要。

我还要指出您对Stephen Toub How do I cancel non-cancelable async operations?的文章以及他在那里创建的WithCancellation扩展的注意。

关于c# - 如何在不关闭流的情况下取消NetworkStream.ReadAsync,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15273752/

10-13 07:49