Wpf 是什么导致触发.NET SerialPort类DataReceived事件?

Wpf 是什么导致触发.NET SerialPort类DataReceived事件?,wpf,.net-3.5,serial-port,Wpf,.net 3.5,Serial Port,我从MSDN文档中了解到,接收到的事件数据不一定每字节触发一次 但有人知道导致事件发生的确切机制吗 接收到每个字节是否会重新启动计时器,该计时器必须在事件触发之前达到(比如字节之间的10毫秒) 我之所以这么问,是因为我正试图编写一个应用程序来读取来自串行端口的XML数据 因为我的笔记本电脑没有串行端口,所以我使用虚拟串行端口模拟器。(我知道,我知道——我对此无能为力) 当我通过模拟端口将数据传递给我的应用程序时,每个XML记录触发一次事件(大约1500字节)。完美的但是,当另一个办公室的同事用实

我从MSDN文档中了解到,接收到的事件数据不一定每字节触发一次

但有人知道导致事件发生的确切机制吗

接收到每个字节是否会重新启动计时器,该计时器必须在事件触发之前达到(比如字节之间的10毫秒)

我之所以这么问,是因为我正试图编写一个应用程序来读取来自串行端口的XML数据

因为我的笔记本电脑没有串行端口,所以我使用虚拟串行端口模拟器。(我知道,我知道——我对此无能为力)


当我通过模拟端口将数据传递给我的应用程序时,每个XML记录触发一次事件(大约1500字节)。完美的但是,当另一个办公室的同事用实际电缆连接的两台计算机尝试此应用程序时,DataReceived事件会在每10个左右字节的XML后重复触发,这会完全破坏应用程序。

DataReceived可以在任何时候触发一个或多个字节准备读取。确切的触发时间取决于操作系统和驱动程序,而且在接收数据和在.NET中触发事件之间会有一个小的延迟

控制流不应依赖于DataReceived事件的计时


相反,请解析底层协议,如果尚未收到完整的消息,请等待更多消息。如果收到多条消息,请确保不要解析第一条消息的剩余部分,因为它们将是下一条消息的开始。

正如Mark Byers指出的,这取决于操作系统和驱动程序。在最低级别,标准RS232芯片(就我而言,我记不起每个人都复制来制作“标准”的芯片的名称)将在其入站寄存器中有数据时触发中断。驱动程序的“底端”必须获取数据(可以是芯片缓冲区大小的任意数量),并将其存储在驱动程序的缓冲区中,然后向操作系统发送信号,表明它有数据。正是在这一点上,.NET framework可以开始发现数据可用。根据操作系统何时向打开串行端口的应用程序发送信号(这是一个操作系统级操作,并提供从.NET framework到操作系统/驱动程序级实现的“真实”链接),缓冲区中可能存在大于1字节的任何数据量,因为驱动程序的底端可能同时加载了更多数据。我敢打赌,在您的系统上,驱动程序提供了一个巨大的缓冲区,并且只有在数据流出现显著停顿后才发出信号。另一方面,你同事的系统发出信号的频率要高得多。同样,马克·拜尔(MarkByer)提出的解析协议的建议是正确的。我在TCP套接字上实现了一个类似的系统,处理这种情况的唯一方法是缓冲数据,直到获得完整的协议消息,然后将完整的消息传递给应用程序。

是的,串行端口数据通常会进行缓冲以提高效率,因此更新的可预测性很低。我做了与Mark所描述的类似的工作,设置了一个计时器,反复调用ReadExisting,处理数据中的所有消息,并保存完成一半的消息。当我使用GPS设备进行此操作时,消息中包含校验和,因此您可以验证其完整性和完整性,以确保它没有被切断(在这种情况下,您将在下一次读取时获取其余消息)。我在一个包装器中使用了它,它依次为每个完整的消息触发一个事件。是的,我最初的体系结构是基于轮询串行端口、缓冲数据、寻找开始和结束标记以提取完整的XML记录,以及缓冲剩余的内容。当我让DataReceived事件工作时,我非常激动,认为这可能会简化整个缓冲场景。但是,唉,我现在必须重新实现缓冲区并再次查找标记。@Klay-实现缓冲区并不是那么糟糕。我的意思是,至少你可以省去投票,这很糟糕!