C # multithreading and UI response cross-thread UI update,
Recently, I was writing a TCP communication program and customized a Communication Class TCPclient for clients to receive and send network messages asynchronously.
TCPclient defines a network message event that receives a new message:
1 // receive the new message event 2 public delegate void initialize enewnetworkmsghandler (string networkMSG); 3 public event initialize enewnetworkmsghandler initialize enewnetworkmsg;
Subscribed to this event in an external form:
void thisClient_receiveNewNetworkMsg( string networkMSG);
At first, the network message is read directly in this function, the command is parsed, And the LoginSuccess event of the form is triggered. The delegate function of the LoginSuccess event will create a New main form.
But the problem is that the new main form is always unresponsive.
After a long time of exploration, I finally come to the following conclusion:
If you define and trigger an event in a custom class, the event processing code in the UI also works in the Custom class thread. To access the control in the UI, You need to invoke
Before that, I always thought that the class in which the event processing function is located should be executed in the corresponding thread during natural operation, so far I can understand where the error is.
According to this conclusion, you cannot directly parse the command and trigger the LoginSuccess event in the thisclient_incluenewnetworkmsg function,
So the following changes are made in the thisClient_receiveNewNetworkMsg function:
1 public delegate void NetMsgDealHandler(string str);2 void thisClient_receiveNewNetworkMsg( string networkMSG) 4 {5 NetMsgDealHandler newMSG = new NetMsgDealHandler(NetMsgDeal);6 BeginInvoke(newMSG, networkMSG);7 }
1 void NetMsgDeal (string networkMSG) {2 XmlDocument xmldoc = new XmlDocument (); 3 try {xmldoc. loadXml (networkMSG);} 4 catch (Exception ex) {MessageBox. show (string. format ("XML loading error ({1}): {0}", networkMSG, ex. message); return;} 5 XmlElement rootElement = xmldoc. childNodes [0] as XmlElement; 6 XmlElement SecElement = rootElement. childNodes [0] as XmlElement; 7 switch (SecElement. name) {8 case "login": {10 if (SecElement. selectSingleNode ("cmd "). innerText = "2") {11 if (SecElement. selectSingleNode ("isSuccess "). innerText = "True") {12 // trigger the LoginSuccess event 13 this. loginSuccess (this); 14} 15 else {16 // trigger loginFailed event 17 this. loginFailed (this); 18} 19} 21} break; 22 // some rows are omitted here 23 default: {MessageBox. show (string. format ("messages that cannot be processed: {0}", networkMSG); return;} 24} 25}
If the main form is executed again, no response is returned. The problem is resolved successfully!