【问题标题】:Serial port DataReceived firing too much串口 DataReceived 触发过多
【发布时间】:2011-11-25 20:28:09
【问题描述】:

我正在处理一个来电显示串行设备并编写以下程序:

serialPort = new SerialPort("COM7", 19200, Parity.None, 8, StopBits.One);
serialPort.DataReceived += serialPort_DataReceived;
serialPort.RtsEnable = true;
serialPort.Encoding = Encoding.ASCII;
serialPort.Open();

void serialPort_DataReceived(object s, SerialDataReceivedEventArgs e)
{
    byte[] data = new byte[serialPort.BytesToRead];
    serialPort.Read(data, 0, data.Length);
    Console.WriteLine(Encoding.ASCII.GetString(data));
}

一开始我接到一个电话,事件完美触发,结果是:"A0101181456926E"

问题在于后续事件...下次我拨打电话时,serialPort_DataReceived 事件会触发很多次,每个事件都有 1 个字符。

是否有任何要设置的属性或要调用的方法来解决此行为?

ps。如果我评论 serialPort.RtsEnable = true; 行,我不会收到任何后续事件。

【问题讨论】:

  • AFAIK 这是正常的行为......类似的事情会发生在 TCP 连接中 - 你必须通过相应地设计协议来处理......
  • 您的ReceivedBytesThreshold 属性是什么值?

标签: c# serial-port


【解决方案1】:

正如 Henk 所说,您可以使用属性 ReceivedBytesThreshold 设置在触发 DataReceived 事件之前要接收的字节数。

但在任何情况下,您都必须处理一次要接收的任意数量的字节。您必须以能够识别消息何时被完全接收的方式设计您的协议。

【讨论】:

    【解决方案2】:

    这是正常行为。您可以更改 ReceivedBytesThreshold 属性,但这样做意味着您必须至少接收该数量,并且如果传输中有任何错误,再次同步可能会很困难。

    我的建议是保留 ReceivedBytesThreshold=1,并将接收到的数据排队,直到您拥有所需的数据。

    【讨论】:

      【解决方案3】:

      我已经完成了通过构建缓冲机制来检测我何时收到基于供应商协议的完整输入字符串的建议。工作正常。 (必须说,并非所有协议设计都提供清晰的开始和结束序列以供使用)我不明白为什么 DataReceived 事件处理程序仍在触发,尽管当我使用 Port.ReadExisting() 方法读取输入缓冲区时,字符串长度为零。阅读https://msdn.microsoft.com/en-us/library/system.io.ports.serialport.receivedbytesthreshold(v=vs.110).aspx 上的 SerialPort.ReceivedBytesThreshold 属性,我意识到即使该属性的默认值为 1,处理程序仍将触发“如果接收到 Eof 字符,无论内部输入缓冲区中的字节数如何”也许这就是为什么处理程序会触发似乎不必要的东西的原因

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多