我试图使用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()调用.
有什么建议?
我正在使用HttpClient.PostAsync(),响应是一个HttpResponseMessage.其Content属性是HttpContent具有CopyToAsync()方法的类型.不幸的是,这是不可取消的.有没有办法将响应复制到a Stream并传递CancellationToken?
我没有被困住CopyToAsync()!如果有解决方法,那就没问题了.就像读取几个字节一样,检查是否取消,继续阅读等等.
这些HttpContent.CreateContentReadStreamAsync()方法看起来像是候选人.不幸的是,它不适用于我选择的个人资料.还不清楚它是否会一次性读取所有数据并浪费大量内存.
注意:我在PCL中使用这个目标是WP8,Windows Store 8,.NET 4.5,Xamarin.iOS和Xamarin.Android
根据问题数量,论坛帖子等,BCL中的TcpClient/NetworkStream实现似乎缺乏对取消IO操作的良好支持.随着.NET 4.5中Async方法的增加,这种缺少取消(或者不错的超时支持)使得事情变得更加令人沮丧,因为在执行IO时取消拒绝监视其CancellationToken的任务变得更加复杂(几乎不可能) .
我已经看到许多实现启动其他线程来监视网络操作并在事情看起来出错时关闭底层流.在我们试图通过使用异步操作来节省这些资源的世界中,这感觉非常脏.
任何人都可以指导我处理有效取消/超时网络IO操作或实际工作的强大第三方实施的指导方向吗?
我使用NetworkStream带TcpClient。
首先我设置我的 tcp 客户端:
tcp = new TcpClient(AddressFamily.InterNetwork)
{ NoDelay = true, ReceiveTimeout = 5000};
Run Code Online (Sandbox Code Playgroud)我的主要数据接收循环:
while (true)
{
//read available data from the device
int numBytesRead = await ReadAsync();
Console.WriteLine($"{numBytesRead} bytes read"); //BP2
}
Run Code Online (Sandbox Code Playgroud)和实际的 TCP 数据读取:
public Task<int> ReadAsync()
{
var stream = tcp.GetStream();
return stream.ReadAsync(InBuffer, 0, InBuffer.Length); //BP1
}
Run Code Online (Sandbox Code Playgroud)我将它连接到一个测试平台,让我可以发送手动数据包。通过设置断点和调试,我检查了stream.ReadTimeout从tcp.
如果我经常发送数据,它会按预期工作。但是如果我不发送任何数据,5 秒后似乎什么也没有发生,没有超时。我看到BP1在调试器中断点被击中,但直到我从我的测试平台发送数据,才被BP2击中。我可以离开它一分钟或更长时间,它似乎只是在等待,但在一分钟后接收发送的数据,这似乎是不正确的行为。5 秒后肯定会发生一些事情(据我所知是一个例外)?
太晚了,所以我期待一些非常基本的东西,但谁能看到我的错误和解决方案?
好的,所以当我对我正在使用的实际 .Net 版本进行 RTFM 时(我有多少次被默认为 .Net …