串行端口通信:轮询串行端口vs使用串行端口DataReceived事件

时间:2009-03-13 21:00:00

标签: c# multithreading serial-port

我正在审查我编写的一些代码,用于与CF2.0上的C#中的串口通信。 我没有使用DataReceived事件,因为它不可靠。 MSDN states that:

  

DataReceived事件不是   保证每个字节都要提高   接收。使用BytesToRead属性   确定剩下多少数据   在缓冲区中读取。

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

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

3 个答案:

答案 0 :(得分:18)

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

我一直都在使用这个活动,并且没有遇到任何麻烦。

答案 1 :(得分:8)

传统观点认为“轮询是坏事”,因为它往往最终成为一个受CPU限制的过程。如果使用阻塞I / O,则CPU可用于其他进程,直到事件发生。

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

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

  

不保证每收到一个字节都会引发DataReceived事件。使用   BytesToRead属性,用于确定在缓冲区中读取多少数据。

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

编辑:在读者线程上执行阻止调用可能是最佳答案。它本身不是轮询,因为线程被阻塞直到字符到达。如果需要在数据到达时处理数据而不是固定大小的块,则可能需要调整缓冲区大小和某些串行端口设置。

答案 2 :(得分:1)