串口通信:轮询串口 vs 使用串口 DataReceived 事件
我只是回顾一下我编写的一些代码,用于在 CF2.0 上用 C# 与串口进行通信。 我没有使用 DataReceived 事件,因为它不可靠。 MSDN 指出:
DataReceived 事件不是 保证每个字节都会升高 已收到。 使用 BytesToRead 属性 确定还剩多少数据 在缓冲区中读取。
我使用 read() 轮询端口,并有一个委托在读取数据时处理数据。 我还在某处读到“民意调查很糟糕”(没有给出解释)。
有什么想法为什么民意调查可能不好吗? 除了通常的线程注意事项之外 - 我有一个单独的线程(后台线程)来轮询端口,该线程在读取数据后退出,所有测试都运行良好。
I am just reviewing some code I wrote to communicate with the serial port in C# on CF2.0.
I am not using DataReceived event since it's not reliable. MSDN states that:
The DataReceived event is not
gauranteed to be raised for every byte
received. Use the BytesToRead property
to determine how much data is left to
be read in the buffer.
I poll the port with read() and have a delegate that processes the data when it is read. I also read somewhere that "polling is bad"(no explanation given).
Any ideas why polling might be bad? aside from the usual threading cautions - I have a separate thread (background thread) that polls the port, the thread is exited after the data is read, all tested and works well.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
按照我的理解,您可能会获得多个字节的一个事件,而不是每个字节一个事件。 我仍然希望在数据准备好时收到一个事件,而不是让它完全“跳过”一些字节。
我一直使用这个事件,并且没有遇到任何问题。
The way I read that, you might get one event for multiple bytes, rather than one event per byte. I would still expect to get an event when data is ready, and not have it "skip" some bytes entirely.
I've always used this event, and have not had any trouble with it.
传统观点认为“轮询是不好的”,因为它通常最终会成为 CPU 密集型进程。 如果改用阻塞 I/O,则 CPU 可用于其他进程,直到事件发生。
也就是说,通常可以进行设置,以便轮询在没有可用字符时返回之前等待(短)超时。 如果选择了合适的超时,那么简单的轮询循环将使用显着更少的 CPU 时间,并且其他进程也可以运行。
我根本没有使用过 C# 中的串行端口,但我会冒险猜测文档的含义
是你不能指望每个角色都会获得一个事件。 在某些情况下,它可能会以多个可用角色来交付事件。 只需检索事件处理程序中的所有可用字符,一切都会好起来的。
编辑:在读取器线程上进行阻塞调用可能是总体上最好的答案。 它本身不是轮询,因为线程在字符到达之前被阻塞。 如果您需要在数据到达时而不是固定大小的块中处理数据,则可能需要调整缓冲区大小和一些串行端口设置。
Conventional wisdom has it that "polling is bad" because it often ends up being a CPU-bound process. If blocking I/O is used instead, then the CPU is available for other processes until the event happens.
That said, it is usually possible to set things up so that a poll waits for a (short) timeout before returning when no characters are available. If a suitable timeout is chosen, then your simple polling loop uses significantly less CPU time, and other processes also get to run.
I haven't used serial ports from C# at all, but I am going to hazard a guess that what the documentation meant by
is that you can't expect to get one event per character. It might under some circumstances deliver the event with more than one character available. Simply retrieve all the available characters in your event handler, and all will be well.
Edit: Doing a blocking call on a reader thread might be the best answer overall. It isn't polling per se since the thread is blocked until characters arrive. You might need to tune the buffer sizes and some of the serial port settings if you need to process the data as it arrives rather than in fixed sized chunks.
我非常确定底层串行端口驱动程序代码是中断驱动的,即使使用阻塞 Read 调用也是如此。
I'm pretty sure the underlying serial port driver code is interrupt driven, even when using the blocking Read call.