C# 串口通信:轮询串口vs使用串口DataReceived事件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/644623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 11:32:47  来源:igfitidea点击:

Serial port communication: polling serial port vs using serial port DataReceived event

c#multithreadingserial-port

提问by sarsnake

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:

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

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.

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

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).

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

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.

任何想法为什么投票可能很糟糕?除了通常的线程注意事项 - 我有一个单独的线程(后台线程)来轮询端口,在读取数据后退出线程,所有这些都经过测试并且运行良好。

采纳答案by Jon B

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.

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

回答by RBerteig

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.

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

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.

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

I haven't used serial ports from C# at all, but I am going to hazard a guess that what the documentation meant by

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

The DataReceived event is not guaranteed to be raised for every byte received. Use the BytesToRead property to determine how much data is left to be read in the buffer.

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

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.

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

回答by Thomas Kj?rnes

I'm pretty sure the underlying serial port driver code is interrupt driven, even when using the blocking Read call.

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