【问题标题】:Async Serial Port with CancellationToken and ReadTimeout具有 CancellationToken 和 ReadTimeout 的异步串行端口
【发布时间】:2018-05-23 04:07:49
【问题描述】:

我正在尝试将 SerialPort 的读取方法包装在一个可以等待的任务中,这样我就可以获得使用 CancellationToken 和 SerialPort 对象超时的好处。我的问题是我似乎无法让任务抛出 CancellationException。这是我的代码...

    static CancellationTokenSource Source = new CancellationTokenSource();

    static void Main(string[] args)
    {
        TestAsyncWrapperToken();
        Console.WriteLine("Press any key to cancel");
        Console.ReadKey(true);
        Source.Cancel();
        Console.WriteLine("Source.Cancel called");
        Console.ReadLine();
    }

    static async void TestAsyncWrapperToken()
    {
        try
        {
            using (var Port = new SerialPort("COM2", 9600, Parity.None, 8, StopBits.One))
            {
                Port.Open();
                var Buffer = new byte[1];
                await Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Starting Read");
                    Port.ReadTimeout = 5000;
                    Port.Read(Buffer, 0, Buffer.Length);                        
                }, Source.Token);
            }
        }
        catch (TaskCanceledException)
        {
            Console.WriteLine("Task Cancelled");
        }
        catch (TimeoutException)
        {
            Console.WriteLine("Timeout on Port");
        }
        catch (Exception Exc)
        {
            Console.WriteLine("Exception encountered {0}", Exc);
        }
    }

是因为 Port.Read 方法是阻塞调用吗?有什么建议?

【问题讨论】:

    标签: c# asynchronous serial-port task cancellation


    【解决方案1】:

    两种方法都是可以想象的。

    1. 使用 ReadAsync
      就是从SreiaPort对象的BaseStream property获取Stream对象,使用Stream.ReadAsync Method (Byte[], Int32, Int32, CancellationToken)

      虽然不是完全匹配的内容,请参考这里。
      How to cancel Stream.ReadAsync?
      NetworkStream.ReadAsync with a cancellation token never cancels

    2. 使用DataReceivedEventSerialDataReceivedEventHandler
      进行更改,使其与 DataReceivedEvent 作为触发器一起使用。
      请参考本文的答案。
      Sample serial port comms code using Async API in .net 4.5?

    附言
    如果您想使用 .NET 4.0 或更低版本,以下文章会有所帮助。
    上面也会有相关知识。
    If you must use .NET System.IO.Ports.SerialPort
    Reading line-by-line from a serial port (or other byte-oriented stream)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-11
      • 1970-01-01
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 2011-10-08
      • 2018-05-22
      相关资源
      最近更新 更多