【问题标题】:How to implement timeout on a .NET Stream when timeouts are not supported on this stream当此流不支持超时时,如何在 .NET 流上实现超时
【发布时间】:2016-02-05 18:46:29
【问题描述】:

我正在尝试在 C# 中使用 Xamarin Android 向蓝牙打印机读取/写入字节。我正在使用System.IO.Stream 来做到这一点。不幸的是,每当我尝试在这些流上使用 ReadTimeoutWriteTimeout 时,我都会收到以下错误:

Message = "此流不支持超时。"

我不希望我的 Stream.Read()Stream.Write() 呼叫无限期地阻塞。我该如何解决这个问题?

【问题讨论】:

    标签: c# android .net xamarin bluetooth


    【解决方案1】:

    您可能希望公开一个带有取消令牌的方法,以便您的 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()

    【讨论】:

    • 有什么办法可以用 Read() 方法做到这一点,还是必须使用 ReadAsync()?
    • 您应该能够使用 Read() 获得相同的结果。
    • 我之所以问,是因为我没有看到任何采用 CancellationToken 的 Read() 方法。
    【解决方案2】:

    您必须在另一个线程上进行读取;在这种情况下,如果您必须停止读取,您可以从其他线程关闭流,读取将完成并出现异常。

    另一种简单的方法是使用 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多