SerialPort.DataRecive使用过程中的注意事项
.NET Framework中提供的串口操作类SerialPort已经用了很多年了,但是今天同事碰到一个问题,给我问住了。
我才发现用了这么多年的SerialPort还是有一些我所不知道的注意事项。
问题描述:同事在SerialPort的DataRecive绑定事件方法中,用了一个while循环,来处理串口接收缓冲区中的数据。但是同样的处理逻辑,放在不同的地方使用,发现不同的问题。
都是在DataRecive事件中,用while循环处理缓冲区数据,但是发现其中一个项目中,DataRecive事件会多次触发,而另一个项目中,会一直在第一次触发DataRecive事件中的while循环中转,不会触发第二次DataRecive事件。
然后搞笑的来了,我当时按照对事件最基本的运行机制的理解,解释说:事件的触发,无论前一次触发有没有完成,都不会影响第二次触发时的执行。所以一直在DataRecive中的while循环中转,肯定是有哪里影响了。
但是后来发现,我的判断错误了。
对于SerialPort中的DataRecive事件来说,前一次触发未完成时,是不会有第二次触发的。
后来反编译了一下SerialPort,证实了上述结论:
public void Open() { if (IsOpen) { throw new InvalidOperationException(SR.GetString("Port_already_open")); } new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); internalSerialStream = new SerialStream(portName, baudRate, parity, dataBits, stopBits, readTimeout, writeTimeout, handshake, dtrEnable, rtsEnable, discardNull, parityReplace); internalSerialStream.SetBufferSizes(readBufferSize, writeBufferSize); internalSerialStream.ErrorReceived += CatchErrorEvents; internalSerialStream.PinChanged += CatchPinChangedEvents; internalSerialStream.DataReceived += CatchReceivedEvents; }
private void CatchReceivedEvents(object src, SerialDataReceivedEventArgs e) { SerialDataReceivedEventHandler dataReceived = this.DataReceived; SerialStream serialStream = internalSerialStream; if (dataReceived == null || serialStream == null) { return; } lock (serialStream) { bool flag = false; try { flag = serialStream.IsOpen && (SerialData.Eof == e.EventType || BytesToRead >= receivedBytesThreshold); } catch { } finally { if (flag) { dataReceived(this, e); } } } }
从上面SerialPort的代码可以看出,对dataRecived事件的调用是加了锁的,也就是说,dataRecived事件如果没有执行完,那么后续是不会再次触发的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本