Swa*_*pie 12 .net c# asynchronous networkstream async-await
我试图使用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");
Run Code Online (Sandbox Code Playgroud)
代码可以很好地接收数据,并且如果continueReading标志设置为false并且接收到数据,则将停止循环,但是在接收到数据之前,它将不会继续通过ReadAsync()行.我无法看到如何在不接收数据的情况下中止呼叫.
我知道ReadAsync的重载提供了一个CancellationToken,但是当NetworkStream没有覆盖默认的ReadAsync行为时,会忽略该令牌(请参阅具有取消令牌的NetworkStream.ReadAsync永远不会取消).
我尝试关闭底层流,这导致等待ReadAsync调用抛出ObjectDisposedException,底层蓝牙连接也被关闭.理想情况下,我不想完全切断与设备的连接,只是为了停止阅读.它似乎不是一种干净的方式,并且感觉不必拆除整个流只是为了中断va ReadAsync()调用.
有什么建议?
您无法取消ReadAsync,因为内部调用是不受管理的并且使用IOCompletion端口.您的选项如下所示.
您可以围绕 NetworkStream.Read(或 ReadAsync)实现一个异步包装器,它还接收一个您可以监控和遵守的取消令牌。像这样的东西:
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);
}
Run Code Online (Sandbox Code Playgroud)
请注意,我只是想说明这个想法,您可能不想考虑返回Task<TResult>,以及是否有 do{}while 循环、任何额外的处理或清理等 - 一切都根据您的需要。
我还想请您注意 Stephen Toub 的文章《如何取消不可取消的异步操作?》以及他在那里创建的 WithCancellation 扩展。
| 归档时间: |
|
| 查看次数: |
9513 次 |
| 最近记录: |