我需要一个串口程序来读取4800
波特的数据。现在我有一个模拟器每秒发送15行数据。它的输出似乎“落后”,无法跟上数据的速度/数量。
我已尝试将ReadLine()
与DataReceieved
事件一起使用,这似乎不可靠,现在我正在使用serialPort.BaseStream.ReadAsync
的异步方法:
okToReadPort = true;
Task readTask = new Task(startAsyncRead);
readTask.Start();
//this method starts the async read process and the "nmeaList" is what
// is used by the other thread to display data
public async void startAsyncRead()
{
while (okToReadPort)
{
Task<string> task = ReadLineAsync(serialPort);
string line = await task;
NMEAMsg tempMsg = new NMEAMsg(line);
if (tempMsg.sentenceType != null)
{
nmeaList[tempMsg.sentenceType] = tempMsg;
}
}
public static async Task<string> ReadLineAsync(
this SerialPort serialPort)
{
// Console.WriteLine("Entering ReadLineAsync()...");
byte[] buffer = new byte[1];
string ret = string.Empty;
while (true)
{
await serialPort.BaseStream.ReadAsync(buffer, 0, 1);
ret += serialPort.Encoding.GetString(buffer);
if (ret.EndsWith(serialPort.NewLine))
return ret.Substring(0, ret.Length - serialPort.NewLine.Length);
}
}
这似乎仍然效率低下,是否有人知道更好的方法来确保从端口读取每个数据并计算?
答案 0 :(得分:3)
一般来说,您的问题是您正在与数据处理同步执行IO。您的数据处理相对昂贵(字符串连接)没有帮助。
要解决一般问题,当你读取一个字节时,将它放入一个处理缓冲区(BlockingCollection
在这里工作很好,因为它解决了生产者/消费者)并从另一个线程读取缓冲。这样,串口可以立即重新开始读取,而不是等待处理完成。
作为旁注,您可能会在代码中使用StringBuilder
而不是字符串连接看到好处。你仍然应该通过队列进行处理。