【问题标题】:Serial port DataReceived event does not fire串口 DataReceived 事件不触发
【发布时间】:2012-05-14 11:54:04
【问题描述】:

我正在开发一个处理串行端口通信的应用程序。这是一个 WPF,多线程应用程序。一切都很顺利,直到我通过 COM 端口发送小包进行通信。

不,我已经到了一个阶段,我必须在 COM 端口上侦听发送到我的应用程序的数据。对于这一大块数据,我遇到了麻烦。我只触发了一个 DataReceived 事件,它读取我需要的部分数据。但在那之后,其余数据不再触发 DataReceived 事件。

如果我监控 COM 端口,我看到字节在那里,监控软件指出,队列中有 2067 个字节,但事件没有触发。

我在 Google 上搜索过类似的问题,但找不到相关的答案。你知道从哪里开始寻找问题的根源吗?

提前致谢。

这是 DataReceived 处理程序的代码:

        private void comPort_DataReceived( object sender, SerialDataReceivedEventArgs e )
    {
        do
        {
            new Thread(() =>
            {
                OnReceivingData(new ComPortCommunicationEventArgs(DataTransferDirections.Receiving, DataTransferActions.Start));
            }).Start();
            byte[] packetData = null;
            try
            {
                IsReceiving = true;
                int bytesToReadCount = comPort.BytesToRead;
                if ( bytesToReadCount == 0 )
                {
                    return;
                }

                packetData = new byte[bytesToReadCount];
                comPort.Read(packetData, 0, bytesToReadCount);
            }
            finally
            {
                IsReceiving = false;
                new Thread(() =>
                {
                    OnReceivingData(new ComPortCommunicationEventArgs(DataTransferDirections.Receiving, DataTransferActions.End));
                }).Start();
            }
            OnPacketReceived(new PacketReceivedEventArgs(comPort.PortName, packetData.ToList()));
        } while ( comPort.BytesToRead > 0 );
    }

我同时发现,如果我注释掉 OnPacketReceived 调用——它只是用接收到的数据为 UI 触发事件——那么数据处理就可以正常工作。所以我认为这不是 COM 端口通信错误...

更新

我找到了解决问题的方法。它与串行端口处理无关。 在我的一个数据处理线程中,我遇到了一个循环,该循环应该在成功处理时完成,但没有足够的数据,它只是连续运行。这样做会阻止 DataReceived 事件处理程序 - 我的原因仍然不完全清楚,因为这两个进程应该在我认为的不同线程上。不过好像我错了。

反正我纠正了处理方法,没有收到来自serisl端口的数据。

很抱歉占用您的时间,无论如何感谢您的帮助,您的想法帮助我解决了这个问题。

兄弟, 沙巴

【问题讨论】:

  • 你能告诉我们你正在使用的代码吗?
  • 我添加了我的 DataReceived 处理程序的代码。我只是从这里通知 UI,在处理程序中什么也不做。我希望它对你有帮助。我是 COM 端口通信领域的新手,所以可能会犯一些小错误...
  • comPort.ReceivedBytesThreshold 设置为什么?
  • 我已经尝试过使用它。现在它设置为 1。大数据包没有任何变化。对于小的,我有更多的事件,但对于大的,它是一样的,它只在前几个字节触发一次。多线程可能会导致一些问题吗?或者锁定某些数据结构?但我认为这至少不应该影响事件的触发。我错了吗?
  • 我发现,如果我注释掉 OnPacketReceived 调用(它只是使用接收到的数据为 UI 触发事件),那么数据处理工作正常。所以我认为这不是 COM 端口通信错误...

标签: c# .net serial-port


【解决方案1】:

我在 5 年前使用 COM 端口,我知道它有时会变得多么棘手。我曾经使用的西门子设备发生了各种棘手的问题:)

首先,我无法完全遵循您的代码,因此我无法确定您的 DataReceived 例程是否正常。我建议您尝试将 comPort_DataReceived 中的所有代码替换为非常简单的代码,仅用于测试目的。

private static void comPort_DataReceived(
                    object sender,
                    SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    Console.WriteLine("Data Received:");
    Console.Write(indata);
}

如果它仍然不起作用,那么问题不在您的代码中。如果你不知道还能尝试什么,我会弄乱SerialPort.DtrEnableSerialPort.RtsEnable 之类的参数,看看是否会发生什么事情,因为这些过去也给我造成了一些非手动错误。


MSDN 中提取的一段代码。

【讨论】:

  • 我有那个页面。但是我不能将事件处理程序直接放入 UI,因为我的应用程序中有一个分开的通信处理层。我必须从我的基本端口处理层通知该层和 UI。
  • 我知道。我只是想让你用这段简单的代码进行测试。你有什么问题吗?
  • 好的,谢谢。我尝试了简单的代码,这很好。我发现,触发事件处理程序 - OnPacketReceived 方法调用 - 会导致数据接收挂起。我仍然不知道为什么,但我正在努力......
  • 好的,让我们调试一下代码。粘贴该方法以便我们查看!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
相关资源
最近更新 更多