C#WPF串行端口连续读取数据

时间:2018-08-04 10:59:03

标签: c# wpf asynchronous serial-port

我正在尝试构建一个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”会不断返回值(使用Hyperterminal测试)。

不胜感激。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

通常来说,您应该避免使用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 ...
    }));
}