16

我只是在查看我编写的一些代码,用于与 CF2.0 上的 C# 中的串行端口进行通信。我没有使用 DataReceived 事件,因为它不可靠。MSDN 指出:

DataReceived 事件不保证为接收到的每个字节引发。使用 BytesToRead 属性来确定缓冲区中还有多少数据要读取。

我使用 read() 轮询端口,并有一个在读取数据时处理数据的委托。我还在某处读到“轮询很糟糕”(没有给出解释)。

任何想法为什么民意调查可能不好?除了通常的线程注意事项 - 我有一个单独的线程(后台线程)来轮询端口,在读取数据后退出线程,所有测试都运行良好。

4

3 回答 3

19

按照我的阅读方式,您可能会为多个字节获得一个事件,而不是每个字节一个事件。我仍然希望在数据准备好时得到一个事件,而不是让它完全“跳过”一些字节。

我一直使用这个事件,并且没有遇到任何问题。

于 2009-03-13T21:06:27.080 回答
9

传统观点认为“轮询很糟糕”,因为它通常最终成为受 CPU 限制的进程。如果改为使用阻塞 I/O,则 CPU 可用于其他进程,直到事件发生。

也就是说,通常可以进行设置,以便轮询等待(短)超时,然后在没有可用字符时返回。如果选择了合适的超时,那么您的简单轮询循环使用的 CPU 时间会显着减少,并且其他进程也可以运行。

我根本没有使用 C# 的串行端口,但我会冒险猜测文档的含义

不保证每个接收到的字节都会引发 DataReceived 事件。使用 BytesToRead 属性来确定缓冲区中还有多少数据要读取。

是您不能期望每个角色获得一个事件。在某些情况下,它可能会提供多个可用字符的事件。只需在事件处理程序中检索所有可用字符,一切都会好起来的。

编辑:在阅读器线程上进行阻塞调用可能是总体上最好的答案。它本身不是轮询,因为线程在字符到达之前被阻塞。如果您需要在数据到达时处理数据而不是固定大小的块,您可能需要调整缓冲区大小和一些串行端口设置。

于 2009-03-13T21:08:20.133 回答
3

我很确定底层串行端口驱动程序代码是中断驱动的,即使在使用阻塞读取调用时也是如此。

于 2010-07-25T18:50:32.237 回答