如何刷新 SerialDevice 的输入缓冲区

How to flush the input buffer of a SerialDevice

我正在创建一个 UWP 应用程序,它需要通过它公开的虚拟串行端口从 USB 输入设备读取数据。

我已经使用 this tutorial 实现了使用 SerialCommunication.SerialDevice class 的工作原型。但是,我需要在首次打开串行端口时刷新输入流,以在应用程序连接到输入设备之前丢弃输入设备缓冲区中可能存在的任何不需要的数据。

显而易见的解决方案似乎是继续读取端口,直到没有任何内容可读为止;像这样:

uint bytes;

do
{
    bytes = await _dataReader.LoadAsync(ReadBufferLength);
    _dataReader.ReadString(bytes);
} while (bytes > 0);

但是,这不起作用,因为如果没有数据可读取,LoadAsync() 将无限期等待。

有没有办法在尝试读取之前查询输入流的内容,或者无条件地刷新它?

感谢您的建议,

蒂姆

更新:为了回应@Hans Passant 的评论,我修改了代码如下,以便在尝试读取之前检测输入缓冲区中的内容:

await Task.Delay(1000);
Debug.WriteLine("BytesReceived: {0}", _serialDevice.BytesReceived); // 0 bytes
var bytesRead = await _dataReader.LoadAsync(ReadBufferLength);
Debug.WriteLine("BytesRead: {0}", bytesRead); // 75 bytes

因此,尽管等待了 1000 毫秒(让设备有足够的时间发送其缓冲区中的内容),BytesReceived 未能检测到任何数据,但 LoadAsync 随后立即读取了 75 个字节。

DataReader.LoadAsync() 在收到一个或多个字节之前不会 return。如果您的输入缓冲区为空,它将阻止您的代码。

您可以使用 CancellationToken 取消读取任务,以便 "flush" 串行输入缓冲区。

下面是实现该技巧的代码。

using (var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(1000)))
{
     await dataReaderObject.LoadAsync(1024).AsTask(cts.Token);
}