我尝试以异步方式从串行端口读取数据,请记住操作所花费的时间不得超过指定的时间段。我使用的代码:
private async Task<int> Read(byte[] buffer, int offset, int length)
{
Console.WriteLine("Reading response to buffer of size {0}, offset {1}, max to cnt {2}", buffer.Length, offset, length);
int totalBytesRead = 0;
Console.WriteLine("Begin reading...");
while (true)
{
Console.WriteLine("Re-entering read");
int bytesRead = 0;
using (CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0, 0, 0, 0, 333))) // 333 ms
{
Console.WriteLine("Waiting for read to complete...");
int tmpOffset = offset + totalBytesRead;
int tmpLength = length - totalBytesRead;
Console.WriteLine("tmpOffset: {0}, tmpLength: {1}", tmpOffset, tmpLength);
try
{
bytesRead = await mPort.BaseStream.ReadAsync(buffer, tmpOffset, tmpLength, cts.Token);
}
catch (Exception e)
{
Console.WriteLine("Exception during read: {0}, stack trace: {1}", e.Message, e.StackTrace);
break;
}
Console.WriteLine("Read completed");
}
totalBytesRead += bytesRead;
Console.WriteLine("Bytes read: {0}, totalBytesRead: {1}, buffer: {2}", bytesRead, totalBytesRead, BitConverter.ToString(buffer, 0, buffer.Length));
if (bytesRead == 0)
{
break;
}
}
Console.WriteLine("Read finished");
return totalBytesRead;
}
以下代码将这些消息返回到控制台:
Reading response to buffer of size 256, offset 0, max to cnt 256
Begin reading...
Re-entering read
Waiting for read to complete...
tmpOffset: 0, tmpLength: 256
Read completed
Bytes read: 1, totalBytesRead: 1, buffer: 52-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
Re-entering read
Waiting for read to complete...
tmpOffset: 1, tmpLength: 255
Read completed
Bytes read: 8, totalBytesRead: 9, buffer: 52-45-4A-30-30-36-4A-44-52-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
Re-entering read
Waiting for read to complete...
tmpOffset: 9, tmpLength: 247
最后一条消息后它挂起。当然,应该使用比 333ms 更长的超时时间。对我来说,令牌似乎永远不会被取消,或者至少永远不会捕获这种取消。我 99% 确定设备不会发送更多数据,因此这就是我指望超时触发的原因。
我是 C# 新手,所以也许有些东西我不太明白。您能看出任务没有被取消的原因吗?
我尝试复制和调整中提出的方法this https://johnthiriet.com/cancel-asynchronous-operation-in-csharp/#cancel-with-a-timeout文章。