我正在尝试将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方法是阻塞调用吗?有什么建议?
答案 0 :(得分:0)
可以想到两种方法。
使用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?
P.S。
如果您想使用.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)