WinForm UI objects can only operate in the UI thread, manipulate UI objects in a non-UI thread, and cause unpredictable errors that require control.invoke or control.begininvoke.
The user thread calls Control.BeginInvoke sends a delegate message to the UI message queue, Control.BeginInvoke does not block the user thread and returns the IAsyncResult object directly.
When the user thread calls Control.endinvoke (IAsyncResult), control.endinvoke blocks the user thread until the delegate executes and returns the return value of the delegate. No return value returns NULL.
Control.Invoke is equivalent to Control.BeginInvoke and Control.endinvoke, which blocks the user thread until the delegate executes and returns the return value of the delegate. No return value returns NULL.
Depending on the class inheritance relationship, you can use BeginInvoke, EndInvoke, Invoke directly in the window.
System. Object
?? System. MarshalByRefObject
???? System.ComponentModel. Component
?????? System.Windows.Forms. Control
???????? System.Windows.Forms. ScrollableControl
?????????? System.Windows.Forms. ContainerControl
???????????? System.Windows.Forms. Form
Examples of experiments:
Form:
Code:
Public Partial classForm1:form { PublicForm1 () {InitializeComponent (); } Private voidButton1_Click (Objectsender, EventArgs e) { //manipulating the UI object in a non-UI thread will cause an error in debug run. //running directly causes the program to be placed at unpredictable risk. NewThread (() ={progressBar1.Value= -; }). Start (); } Private voidButton2_Click (Objectsender, EventArgs e) { NewThread (() = { varresult = This. Invoke (Newfunc<int,int,string> (n1, n2) = { for(inti =0; I <= -; i + =Ten) {progressBar1.Value=i; Thread.Sleep ( $); } return(n1+n2). ToString (); }), -, +); MessageBox.Show (result. GetType (). ToString ()+":"+result); }). Start (); } Private voidButton3_Click (Objectsender, EventArgs e) { NewThread (() ={IAsyncResult AsyncResult= This. BeginInvoke (Newfunc<int,int,string> (n1, n2) = { for(inti =0; I <= -; i + =Ten) {progressBar1.Value=i; Thread.Sleep ( $); } return(N1 +n2). ToString (); }), $, +); MessageBox.Show ("BeginInvoke won't block ."); varresult = This. EndInvoke (AsyncResult); MessageBox.Show ("EndInvoke will block,"+ result. GetType (). ToString () +":"+result); }). Start (); } Private voidButton4_Click (Objectsender, EventArgs e) { //two delegates in succession, since the UI thread has only one, two delegates can only execute successively NewThread (() ={IAsyncResult ASYNCRESULT1= This. BeginInvoke (Newfunc<int,int,string> (n1, n2) = { for(inti =0; I <= -; i + =Ten) {progressBar1.Value=i; Thread.Sleep ( $); } return(N1 +n2). ToString (); }), $, +); IAsyncResult ASYNCRESULT2= This. BeginInvoke (Newfunc<int,int,string> (n1, n2) = { for(inti =0; I <= -; i + =Ten) {Progressbar2.value=i; Thread.Sleep ( $); } return(N1 +n2). ToString (); }), -, -); MessageBox.Show ("BeginInvoke won't block ."); varRESULT1 = This. EndInvoke (ASYNCRESULT1); MessageBox.Show ("EndInvoke (ASYNCRESULT1) return"); varRESULT2 = This. EndInvoke (ASYNCRESULT2); MessageBox.Show ("EndInvoke (ASYNCRESULT2) return"); MessageBox.Show (RESULT1. GetType (). ToString ()+":"+ RESULT1 +"\ r \ n"+result2. GetType (). ToString ()+":"+result2); }). Start (); } Private voidButton5_click (Objectsender, EventArgs e) { //to wait for the precision Bar update to complete, click to respondMessageBox.Show ("ha"); } Private voidButton6_click (Objectsender, EventArgs e) {progressBar1.Value=0; Progressbar2.value=0; } }
View Code
System.Windows.Forms.Control.Invoke and BeginInvoke