我以前使用过串行端口及其原始方法,如 BytesToRead、Read 和 Write。据说这些是不可靠的,我有很多忙等待我试图切换到它的异步方法。
我需要从具有 2 个不同超时的串行端口读取。第一次超时在两条消息之间(此处为 2000 毫秒),第二次超时在 2 个字符之间(此处为 10 毫秒)。因此,我为每个 ReadAsync 调用更改 ReadTimeout,如下所示:
public int Read(byte[] buffer, int offset, int count, bool isFirstChar)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
try
{
m_serialPort.ReadTimeout = isFirstChar ? 2000 : 10;
Task<int> task = m_serialPort.BaseStream.ReadAsync(buffer, offset, count);
task.Wait();
return task.Result;
} catch (AggregateException err)
{
stopWatch.Stop();
int cnt = 0;
foreach (Exception e in err.InnerExceptions)
{
if (e is TimeoutException)
{
Console.WriteLine(string.Format("Exception {0}: {1} Timeout: {2} ms", ++cnt, e.Message, stopWatch.ElapsedMilliseconds));
}
}
return -1;
}
}
发生 AggregateException 且未收到任何字节时的输出:
异常 1:操作已超时。超时:2014 毫秒
异常 1:操作已超时。超时:2014 毫秒
异常 1:操作已超时。超时:2014 毫秒
异常 1:操作已超时。超时:2014 毫秒
异常 1:操作已超时。超时:2014 毫秒
异常 1:操作已超时。超时:3584 毫秒
异常 1:操作已超时。超时:2014 毫秒
异常 1:操作已超时。超时:2017 毫秒
异常 1:操作已超时。超时:2012 毫秒
异常 1:操作已超时。超时:2011 毫秒
异常 1:操作已超时。超时:2016 毫秒
异常 1:操作已超时。超时:2012 毫秒
异常 1:操作已超时。超时:2011 毫秒
异常 1:操作已超时。超时:2013 毫秒
异常 1:操作已超时。超时:2013 毫秒
我现在的问题是:
- 这是将 ReadAsync 方法与 .Wait() 一起使用的正确方法吗?
- 每次调用 ReadAsync 之前都可以更改 ReadTimeout 吗?
- 我是否应该在 ReadAsync 中使用 CancellationToken 作为参数,如果是,最好的方法是什么?