C# 使用 .NET 框架读取串行端口的正确方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13754694/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 09:41:12  来源:igfitidea点击:

What is the correct way to read a serial port using .NET framework?

c#serial-port.net-4.5

提问by Yannick Blondeau

I've read a lot of questions here about how to read data from serial ports using the .NET SerialPort class but none of the recommanded approaches have proven completely efficient for me.

我在这里阅读了很多关于如何使用 .NET SerialPort 类从串行端口读取数据的问题,但没有一种推荐的方法对我来说是完全有效的。

Here is the code I am using for now:

这是我现在使用的代码:

SerialPort port = new SerialPort("COM1");
port.DataReceived += new SerialDataReceivedEventHandler(MyDataReceivedHandler);

And the event handler:

和事件处理程序:

void MyDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    int count = port.BytesToRead;
    byte[] ByteArray = new byte[count];
    port.Read(ByteArray, 0, count);
}

But I am still missing some data sometimes. I've tried different way of reading the data in the event handler but with no luck.

但有时我仍然会丢失一些数据。我尝试了不同的方式来读取事件处理程序中的数据,但没有成功。

As the .NET 4.5 brings new possibilities to do some asynchronous tasks, like with the ReadAsyncmethod that seems to be useable on a SerialPort stream, I'm curious to see what would be the recommended approach to handle those cases.

由于 .NET 4.5 为执行某些异步任务带来了新的可能性,例如似乎可用于 SerialPort 流的ReadAsync方法,我很想知道处理这些情况的推荐方法是什么。

采纳答案by MethodMan

Could you try something like this for example I think what you are wanting to utilize is the port.ReadExisting()Method

你可以尝试这样的事情,例如我认为你想要利用的是port.ReadExisting()方法

 using System;
 using System.IO.Ports;

 class SerialPortProgram 
 { 
  // Create the serial port with basic settings 
    private SerialPort port = new   SerialPort("COM1",
      9600, Parity.None, 8, StopBits.One); 
    [STAThread] 
    static void Main(string[] args) 
    { 
      // Instatiate this 
      SerialPortProgram(); 
    } 

    private static void SerialPortProgram() 
    { 
        Console.WriteLine("Incoming Data:");
         // Attach a method to be called when there
         // is data waiting in the port's buffer 
        port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); 
        // Begin communications 
        port.Open(); 
        // Enter an application loop to keep this thread alive 
        Console.ReadLine();
     } 

    private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
       // Show all the incoming data in the port's buffer
       Console.WriteLine(port.ReadExisting()); 
    } 
}

Or is you want to do it based on what you were trying to do , you can try this

或者你想根据你想做的事情去做,你可以试试这个

public class MySerialReader : IDisposable
{
  private SerialPort serialPort;
  private Queue<byte> recievedData = new Queue<byte>();

  public MySerialReader()
  {
    serialPort = new SerialPort();
    serialPort.Open();
    serialPort.DataReceived += serialPort_DataReceived;
  }

  void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
  {
    byte[] data = new byte[serialPort.BytesToRead];
    serialPort.Read(data, 0, data.Length);
    data.ToList().ForEach(b => recievedData.Enqueue(b));
    processData();
  }

  void processData()
  {
    // Determine if we have a "packet" in the queue
    if (recievedData.Count > 50)
    {
        var packet = Enumerable.Range(0, 50).Select(i => recievedData.Dequeue());
    }
  }

  public void Dispose()
  {
        if (serialPort != null)
        {
            serialPort.Dispose();
        }
  }

回答by MethodMan

I used similar code to @MethodMan but I had to keep track of the data the serial port was sending and look for a terminating character to know when the serial port was done sending data.

我使用了与@MethodMan 类似的代码,但我必须跟踪串行端口发送的数据并查找终止字符以了解串行端口何时完成发送数据。

private string buffer { get; set; }
private SerialPort _port { get; set; }

public Port() 
{
    _port = new SerialPort();
    _port.DataReceived += new SerialDataReceivedEventHandler(dataReceived);
    buffer = string.Empty;
}

private void dataReceived(object sender, SerialDataReceivedEventArgs e)
{    
    buffer += _port.ReadExisting();

    //test for termination character in buffer
    if (buffer.Contains("\r\n"))
    {
        //run code on data received from serial port
    }
}

回答by Vimukthi Sineth

    using System;
    using System.IO.Ports;
    using System.Threading;

    namespace SerialReadTest
    {
        class SerialRead
        {
            static void Main(string[] args)
            {
        Console.WriteLine("Serial read init");
        SerialPort port = new SerialPort("COM6", 115200, Parity.None, 8, StopBits.One);
        port.Open();
        while(true){
          Console.WriteLine(port.ReadLine());
        }

    }
}
}