在.net中读取串口的最快方法是什么?

时间:2016-12-28 20:31:01

标签: c# .net asynchronous serial-port

我需要一个串口程序来读取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);
            }
        }

这似乎仍然效率低下,是否有人知道更好的方法来确保从端口读取每个数据并计算?

1 个答案:

答案 0 :(得分:3)

一般来说,您的问题是您正在与数据处理同步执行IO。您的数据处理相对昂贵(字符串连接)没有帮助。

要解决一般问题,当你读取一个字节时,将它放入一个处理缓冲区(BlockingCollection在这里工作很好,因为它解决了生产者/消费者)并从另一个线程读取缓冲。这样,串口可以立即重新开始读取,而不是等待处理完成。

作为旁注,您可能会在代码中使用StringBuilder而不是字符串连接看到好处。你仍然应该通过队列进行处理。