【问题标题】:C#: wait for serial port to close()C#:等待串口关闭()
【发布时间】:2015-10-08 03:14:32
【问题描述】:

我想实现一个相当简单的函数,输出串口的字节数组,例如

byte[] o = readAllDataFromSerialPort();

实现了实际的串口功能。我使用串口接收一些数据,并通过事件DataReceived处理数据。

sp = new SerialPort(portname, 9600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One);
sp.Handshake = Handshake.None;
sp.DataReceived += new SerialDataReceivedEventHandler(serialDataReceived);

我检查接收到的数据是否有“消息结束”包,以便关闭串行端口,等等。喜欢

if (data = "UA") sp.Close()

所以基本上我想做的是等待关闭,然后再返回数据,这样在顶级视图上程序不会继续,直到数据到达。但是,我无法理解如何以有效和优雅的方式实现这种“等待”,因为我的数据依赖于事件。任何提示或线索或示例将不胜感激。

【问题讨论】:

  • 等待是个很糟糕的主意,很可能导致死锁。普遍的建议适用,只是不要打扰。你只是在你的程序中添加失败模式,根本没有任何好处。

标签: c# serial-port


【解决方案1】:

串行端口未打开或关闭。 OpenClose 函数打开串行端口驱动程序的句柄。

如果没有对驱动程序打开句柄,则忽略来自端口的所有输入。

确定是否已收到所有数据的唯一方法是设计一种协议,为您提供有保证的方法来检测传输结束。

您可以通过以下方式之一做到这一点:

  • 选择一个唯一的终止符作为消息的结尾,

  • 在消息的开头添加一个长度,指示剩余数据量,或

  • 等待足够长的时间(这也取决于)以确保没有更多数据待处理。

OpenClose 隐喻的另一个原因是,串行端口通常是专有资源,一次只有一个进程可以访问句柄,以防止不兼容(并且可能是危险的)访问端口另一端的设备无意中。您应该在整个程序中保持端口打开,以防止连接的设备因为另一个程序不恰当地打开设备而变得不可访问。

缺乏热插拔功能(实际上是设备识别)使得串行端口更加静态,保持设备打开应该不是问题。

您似乎赞成第三种选择。通过重置每次接收数据时设置的计时器来实现这一点,如果超时则假设传输完成。

【讨论】:

    【解决方案2】:

    正如 SerialPort.Close() 文档中所述:

    任何应用程序的最佳做法是在调用 Close 方法后等待一段时间,然后再尝试调用 Open 方法,因为端口可能不会立即关闭。

    没有办法等待它关闭。您可以将其称为“错误”或“设计的功能”

    使用同一程序一遍又一遍地OpenCloseSerialPort 是一种不好的做法。您应该保持 SerialPort 处于打开状态。

    如果你真的想关闭它并稍后再次打开它,你可以在返回之前添加一个小睡眠,但没有意义的睡眠是不好的做法。

    我发现了这个不错的帖子https://stackoverflow.com/a/10210279/717559 有一个很好的报价:

    这是“最佳实践”建议最糟糕的做法,因为它根本没有具体说明您应该等待多长时间。

    【讨论】:

    • 感谢您的建议,但是我仍然想关闭端口,因为我在程序的不同部分使用它。关于如何实现我的想法的任何想法?
    • 我明白,最好有一个 SerialManager 类(可能是单格顿),你的程序的所有部分都将通过这个类访问序列。那么你就不需要一遍又一遍地关闭和打开它。这有意义吗?
    猜你喜欢
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多