我正在尝试使用C#中的Xamarin Android向/从蓝牙打印机读取/写入字节。我正在利用System.IO.Stream
来做到这一点。不幸的是,每当我尝试在这些流上使用ReadTimeout
和WriteTimeout
时,我都会收到以下错误:
Message =“此流不支持超时。”
我不希望我的Stream.Read()
和Stream.Write()
调用无限期阻止。我该如何解决这个问题?
答案 0 :(得分:0)
你必须在另一个线程上进行读取;在这种情况下,如果您必须停止读取,则可以从其他线程关闭流,并且读取将以异常结束。
另一种简单的方法是使用System.Threading.Timer来处理流:
Stream str = //...
Timer tmr = new Timer((o) => str.Close());
tmr.Change(yourTimeout, Timeout.Infinite);
byte[] data = new byte(1024);
bool success = true;
try{ str.Read(data, 0, 1024); }
catch{ success = false, }
finally{ tmr.Change(Timeout.Inifinite, Timeout.Infinite); }
if(success)
//read ok
else
//read timeout
答案 1 :(得分:0)
您可能希望公开一个带有取消令牌的方法,以便您的api可以轻松消耗。
其中一个CancellationTokenSource构造函数将TimeSpan作为参数。另一方面,CancellationToken暴露了Register方法,该方法允许您关闭流,并且读取操作应该在抛出异常时停止。
方法调用
var timeout = TimeSpan.Parse("00:01:00");
var cancellationTokenSource = new CancellationTokenSource(timeout);
var cancellationToken = cancellationTokenSource.Token;
await ReadAsync(stream, cancellationToken);
方法实施
public async Task ReadAsync(Stream stream, CancellationToken cancellationToken)
{
using (cancellationToken.Register(stream.Dispose))
{
var buffer = new byte[1024];
var read = 0;
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
// do stuff with read data
}
}
}
以下代码仅在超时时才会处理流
更多可以找到here。
编辑:
将.Close()更改为.Dispose(),因为某些PCL中不再提供它.Close() vs .Dispose()