2016-12-28 77 views
1

我需要一个串口程序来读取以4800波特进入的数据。现在我有一个模拟器每秒发送15行数据。它的输出似乎“后面”,并跟不上数据进入的速度/数量。在.net中读取串行端口的最快方法是什么?

我尝试使用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

您是否尝试过'ReadExisting'并解析传入的数据?如果你每秒读一遍,你应该有足够的时间 –

+1

一次读一个字节的串口似乎很奇怪。下面是一个可靠地(根据作者)读取串行端口的方法的快速网络示例。 http://www.sparxeng.com/blog/software/must-use-net-system-io-ports-serialport 通过谷歌搜索发现它。 – PhillipH

+0

@PhillipH:我的博客文章没有介绍如何设置缓冲区大小,因为它对设备和协议非常特殊。通常我会设置一个字符间超时,但.NET并不那么容易。而杰里通过切换到'port.BaseStream.ReadAsync'已经接受了我的建议。 –

回答

3

一般来说,你的问题是你正在与数据处理同步执行IO。它不利于您的数据处理相对昂贵(字符串连接)。

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

作为一个方面说明,您可能会在代码中使用StringBuilder而不是字符串连接,从而可能会看到好处。你仍然应该通过队列来处理。

+0

感谢您的提示!它似乎与BlockingCollection一起工作得更好。一旦我修改了字符串,就会有更多的改进 – jerryn44

相关问题