首页 > 解决方案 > 从串行 com 端口读取的增量延迟

问题描述

我正在构建一个同时从两个串行端口读取的 WPF 应用程序。一个端口(称重机)上的设备每秒发送一个 7 个字符的字符串。第二个端口(牛奶分析仪机器)上的设备在机器上手动按下按钮时发送 275 个字符串。

我正在使用以下代码在启动时配置和打开端口:

//serial port for Milk Machine
serialPortMilk = new SerialPort
            {
                PortName = EnVar.GlobalSetting.MilkMachinePort,
                BaudRate = EnVar.GlobalSetting.MilkMachineBaudRate,
                Handshake = Handshake.None,
                Parity = Parity.None,
                DataBits = EnVar.GlobalSetting.MilkMachineDataBits,
                StopBits = StopBits.One,
                ReadTimeout = 1000,
        };

        serialPortMilk.DataReceived += new SerialDataReceivedEventHandler(RecieveMilk);
        serialPortMilk.Open();


//serial port for Weighing Machine
 serialPortWeight = new SerialPort
 {
              PortName = EnVar.GlobalSetting.WeightMachinePort,
                    BaudRate = EnVar.GlobalSetting.WeightMachineBaudRate,
                    Handshake = Handshake.None,
                    Parity = Parity.None,
                    DataBits = EnVar.GlobalSetting.WeightMachineDataBits,
                    StopBits = StopBits.One,
                    ReadTimeout = 300,
                    WriteTimeout = 500,
                };

                serialPortWeight.DataReceived += new SerialDataReceivedEventHandler(ReceiveWeight);
                serialPortWeight.Open();

我能够连续从称重机读取数据,并且该值每秒在应用程序 UI 中正确更新。

我面临的问题是:当用户按下牛奶机上的按钮并在端口上发送数据时,需要 4-5 秒才能触发 DataReceived 事件。如果我继续这样做,即再次按下机器上的按钮,下一个 DataReceive 事件将在 8-10 秒后触发。这种延迟不断增加。另一个事实是,如果我关闭称重机端口并保持牛奶机端口打开,牛奶机端口的 DataReceived 事件会立即触发。

这就是我在 ReceiveMilk 委托中所做的事情:

try
{
  machineData = serialPortMilk.ReadLine();
  serialPortMilk.DiscardInBuffer();
}
catch (Exception ex)
{
  return;
}

//string operations

Dispatcher.Invoke(new Action(() =>
{
  //set values in UI
}}));

并且在 ReceiveWeight 委托中几乎相似。

我在阅读之前/之后尝试了不同的超时、读取缓冲区、线程睡眠..但没有解决这个问题。

标签: c#wpfserial-port

解决方案


这是我在涉及多个s时使用DataReceived事件时看到的常见问题。如果你用谷歌搜索这个问题,你会发现这是一个古老的问题。 SerialPort

请参阅此 MSDN 线程。引用其中一个回复:“.NET SerialPort 不是一个很好的组件”。有些人报告说调整ReceivedBytesThreshold值取得了成功。大多数人不得不求助于轮询数据,而不是基于事件的方法(也在此处)。

首先尝试使用阈值,因为这对您来说可能是一个快速的胜利。否则,可能需要重构。


推荐阅读