Windows 事件与跨线程调用
2026/6/1 16:59:40 网站建设 项目流程

需求

当我们新建一个类,通常会遇到当类的一个属性变化时,如何通知用户?比如串口收到数据,tcp 或UDP 收到网络数据时,如何及时通知用户?
1、查询是否收到,若收到,在文本框显示。
2、专门新增加一个线程,专门负责接收数据。当有数据收到时,通过“数据已收到”事件,用事件处理程序,来更新文本框。
第一种方法简单,但十分占用资源。第二种方法,涉及事件及线程安全问题。

现以第二种方法为例,进行说明。

(1) 在类中声明事件处理程序

publicdelegatevoidReiceivedDataChgEventHandler(object sender,ReceivedDataChgEventArgsargs);publicReiceivedDataChgEventHandler?ReceivedDataChg;

(2)在数据的set 方法中,加入事件处理

publicstringReceivedData{set{string oldValue=receivedData??"";string newValue=value??"";receivedData=value;NewData=true;OnReceivedDataChg("receivedData",oldValue,newValue);}}privatestring?receivedData;publicvirtualvoidOnReceivedDataChg(string name,object oldValue,object newValue){if(ReceivedDataChg!=null){ReceivedDataChg.Invoke(this,newReceivedDataChgEventArgs(name,oldValue,newValue));}}

3、在form中,新建类,并为ReceivedDataChg增加处理程序。特别要说明的时,由于类form并不时由serialPort类创建的,由类的实例调用form中的控件时,windows 认为类越权了。所以需要由textBox2反过来调用类的事件处理程序 “setText"。

是不是有点绕。

privatevoidbutton1_Click(object sender,EventArgse){string portName=comboBox1.SelectedItemas string??"com1";sp=new(portName,115200,8,"1",SerialPortC.ParityBits.None);sp.ReceivedDataChg+=SetText;if(sp._serialPort.IsOpen){this.textBox1.Text="AT";sp.Writeline("AT");}}publicvoidSetText(object sender,ReceivedDataChgEventArgsargs){if(this.textBox2.InvokeRequired){this.textBox2.Invoke(SetText,this.textBox2,args);}else{this.textBox2.AppendText((string)args.NewValue);}}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询