具有CancellationToken和ReadTimeout的异步串行端口
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了具有CancellationToken和ReadTimeout的异步串行端口相关的知识,希望对你有一定的参考价值。
我正在尝试将SerialPort的read方法包装在一个可以等待的任务中,这样我就能从使用CancellationToken和SerialPort对象的超时中获益。我的问题是我似乎无法让Task抛出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方法是阻塞调用吗?有什么建议?
答案
可以想到两种方法。
- 使用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
- 使用DataReceivedEvent和SerialDataReceivedEventHandler 进行更改,以便将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)
以上是关于具有CancellationToken和ReadTimeout的异步串行端口的主要内容,如果未能解决你的问题,请参考以下文章
连续 WebJobs 和 CancellationToken
我应该如何使用 DataflowBlockOptions.CancellationToken?