如何在不关闭流的情况下取消NetworkStream.ReadAsync
我试图使用NetworkStream.ReadAsync()来读取数据,但我无法找到如何在调用时取消ReadAsync()。 对于后台,NetworkStream由连接的BluetoothClient对象(来自32Feet.NET蓝牙库)提供给我。
我正在尝试的当前get-it-working代码如下。
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行为,所以会忽略该令牌(请参阅带有取消令牌的NetworkStream.ReadAsync永远不会取消 )。
我试过关闭底层流,这导致等待ReadAsync调用抛出ObjectDisposedException,底层蓝牙连接也被关闭。 理想情况下,我不想完全切断与设备的连接只是为了停止阅读。 它似乎不是一种干净的方式,并且感觉不必拆除整个流只是为了中断va ReadAsync()调用。
任何建议?
您可以在NetworkStream.Read(或ReadAsync)周围实现异步包装,它还会收到您可以监控并自己尊重的canceltoken。 像这样的东西:
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
,以及是否有do {} while循环,任何额外的处理或清理等等 – 都根据你的需要。
我还要注意Stephen Toub的文章如何取消不可取消的异步操作? 以及他在那里创建的WithCancellation扩展。
您无法取消ReadAsync,因为内部调用是非托管的并且使用IOCompletion端口。您的选项如下所示。
- 使用Socket.Shutdown()。 这将返回ReadAsync,套接字错误为OperationAborted。
- 等待读取超时。
- 在从sockets读取数据之前检查数据是否可用。
我通过让Task等待异步调用和await语句之间的取消令牌调用来管理取消,如下所示:
上述就是C#学习教程:如何在不关闭流的情况下取消NetworkStream.ReadAsync分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
try { .... Task readTask = input.ReadAsync(buffer, 0, buffer.Length); readTask.Wait(myCancellationToken); int readBytes= await readTask; .... } catch ( OperationCanceledException e ) { // handle cancellation }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1000823.html