我正在使用SerialPort与设备通讯。该设备具有RS-485,另一侧(PC)是RS-232(虚拟端口)。设备可以正常工作,发送和接收数据。
问题是,有时不会触发DataReceived事件。我每10秒钟使用System.Timer将数据发送到设备。在大多数情况下,它运行良好,但是每隔1-10分钟我没有得到响应,然后,在经过2-4次以上的操作后,最终触发了DataReceived事件,并且我得到了一个数据簇(之前我“询问”的所有信息) for是在缓冲区中)。
我的问题是:那怎么可能?
对不起,我不能在此处放置代码示例,但是我的应用程序中没有多线程(只有主线程以及带有Timer_Elapsed和DataReceived事件的线程,我认为它们是在单独的线程上引发的),我的DataReceived事件是处理速度快,不应并行提高(10秒足够长,设备响应时间低于1秒)。如果我使用Thread.Sleep,它将在我确定不会与任何东西发生冲突的地方。
它可能更多是硬件问题,而不是软件问题,因为当我使用其他应用程序测试COM端口时,COM端口的行为与此类似(其中一个是设备制造商提供的用于测试连接的端口,看上去不像(如果它是用C#编写的)。但是我对硬件不是很好。也许PC或COM端口有问题(不是内置的,而是外部的)?或者它可能是与操作系统相关的事情(我的应用是在Windows Server 2003下运行的Windows服务)。
最佳答案
在我看来,您没有按预期冲走缓冲区。
不保证每个接收到的字节都会引发DataReceived事件。使用
BytesToRead属性确定缓冲区中还有多少数据要读取。
见http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx
(顺便说一句,DataReceived事件确实在辅助线程上引发。)
您是否尝试过调整ReadBufferSize和ReceivedBytesThreshold属性?那就是我要开始调查的地方。您知道消息的大概大小吗?您可能希望将ReceivedBytesThreshold属性设置为刚好低于您希望从设备接收的最小消息大小。然后,您可能需要短暂的忙碌等待以获取最后几个字节来完成消息。