【问题标题】:C# WPF Serial Port Reading data continuouslyC# WPF 串口连续读取数据
【发布时间】:2018-08-04 10:59:03
【问题描述】:

我正在尝试构建一个 WPF 应用程序,该应用程序可以从串行端口读取数据并且不会阻塞 UI 线程,但我对应该如何做有点卡住了。

我的 *.xaml.cs 文件中的代码如下

private void testConnection_Click(object sender, RoutedEventArgs e)
{
    string correctPort = "COM6";
    SerialPortConnection serialPortTestConnection = new SerialPortConnection(correctPort);

}

在我的 SerialPortCommunications 中,我得到了这样的结果:

public SerialPortCommunications(string comPort)
{
        SerialPort mySerialPort = new SerialPort(comPort);
        mySerialPort.BaudRate = 2400;
        mySerialPort.Parity = Parity.None;
        mySerialPort.StopBits = StopBits.One;
        mySerialPort.DataBits = 7;
        mySerialPort.Handshake = Handshake.None;
        mySerialPort.Encoding = ASCIIEncoding.ASCII;

        mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);

        mySerialPort.Open();
        mySerialPort.WriteLine("C");
}

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    String s = sp.ReadExisting();
    if (s == "\r")
    {
        Console.WriteLine(tempReadingString);
        tempReadingString = string.Empty;
    } else
    {
        tempReadingString += s;
    }
}

我确实收到了设备的第一个响应,但是即使端口保持打开状态,它也会在此之后停止。我确信传递值“C”会不断返回值(使用超级终端测试)。

不胜感激。

【问题讨论】:

    标签: c# wpf asynchronous serial-port


    【解决方案1】:

    一般来说,您应该避免使用 ReadExisting,它存在已知问题,尤其是当传入流包含二进制数据时。这是我的工作:

    this.SerialDevice = new SerialPort(this.Port);
    this.SerialDevice.BaudRate = 115200;
    this.SerialDevice.DataReceived += OnDataReceived;
    this.SerialDevice.Open();
    ...
    private void OnDataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        var serialDevice = sender as SerialPort;
        var buffer = new byte[serialDevice.BytesToRead];
        serialDevice.Read(bytes, 0, buffer.Length);
    
        // process data on the GUI thread
        Application.Current.Dispatcher.Invoke(new Action(() => {
            ... do something here ...
        }));
    }
    

    【讨论】:

      【解决方案2】:

      您应该将您的 SerialPortCommunications 类的对象放在一个新线程中,然后开始从 COM 端口读取数据。此外,如果您需要来自 WPF 中 COM 端口的数据,例如 TextBlock,您需要在 SerialPortCommunications 类中创建一个事件,并在 WPF 中实现一个事件处理程序。但在该处理程序中,您将需要使用 Dispatching 来显示该 TextBlock 中的数据。

      【讨论】:

      • 感谢您的回复。我尝试将它添加到这样的线程中:` Thread test = new Thread(() => { SerialPortConnection serialPortTestConnection = new SerialPortConnection("COM6"); });测试.开始(); ` 但是没有运气,它只返回一次响应并且似乎正在断开连接,然后如果我再次连接它会再次返回值并保持连接。
      • 永远不要直接在 C# 中创建线程,如果您决定在不同的线程中运行代码,那么请改用任务。 Stephen Cleary 的书“C# 中的并发”基本上是这方面的圣经,并且有这样的说法:“只要你输入 new Thread(),就结束了;你的项目已经有遗留代码。”
      猜你喜欢
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      • 2020-04-26
      • 1970-01-01
      • 1970-01-01
      • 2016-05-15
      相关资源
      最近更新 更多