Dot Net (C #): Invoke () method for multi-threaded applications with windows forms a
Control on a windows forms from another thread
from, the
Invoke () method of the form or controls are used.
A Control can only be changed by the thread from which it was created! following minimal example (incomplete
) shows a use case in which a thread reports its status to a form: The class
MathClass generated
Thread objects whose method
CalcBackground () should ausgefürt in a thread wird.Aus this method out the GUI on the current thread state
be informed:
1:
2: public class MathClass
3: { 4:
5: private MainForm myForm;
6: private int iNumber ;
7:
8: public Thread Initialize(MainForm myform, int number)
9: { 10: this .myForm = myform;
11: this .iNumber = number;
12: return new Thread( new ThreadStart( this .CalcBackground));
13: }
14:
15: delegate void UpdateUI( int number, int state);
16: delegate void Finish( int number);
17:
18: public void CalcBackground()
19: { 20: UpdateUI updateUI = new UpdateUI( this .myForm.updateUIProc);
21: Finish finish = new Finish( this .myForm.FinishThread);
22:
23: try
24: { 25: // do something
26: // ...
27: // report status to form:
28: object [] param = new object [2] { this .iNumber, i }; 29: myForm.Invoke(updateUI, param); // call myForm.updateUIProc(iNumber, i)
30: }
31: catch (ThreadAbortException)
32: { 33: // clean up
34: }
35: catch (Exception)
36: { 37: // catch any other exception
38: }
39: finally
40: { 41: try
42: { 43: // call myForm.FinishThread(iNumber)
44: myForm.Invoke(finish, new object [] { this .iNumber }); 45: }
46: catch (ObjectDisposedException e)
47: { 48: }
49: catch (Exception ee)
50: { 51:
} 52:}
53:}
54:
55:}
created the Main form in the method StartThreads () two new threads. The methods
updateUIProc () finish and thread () be started by Invoke () method of thread from the thread and run myself
the Main Form :
1: public partial class MainForm : Form
2: { 3:
4: public MainForm()
5: { 6: InitializeComponent();
7: }
8:
9: private void Form1_FormClosing( object sender, FormClosingEventArgs e)
10: { 11: // kill threads before form closes
12: if (anyThreadAlive)
13: { 14: killThreads();
15: }
16: }
17:
18: public void updateUIProc( int number, int val)
19: { 20: this .textBox1.AppendText(
21: string .Format( "thread {0} has done {1} % of its job" , number, val)); 22: }
23:
24: public void FinishThread( int number)
25: { 26: this .textBox1.AppendText(
27: string .Format( "thread {0} has finished" , number)); 28: }
29:
30: private void startThreads()
31: { 32: Thread th1 = new MathClass().Initialize( this , 0);
33: Thread th2 = new MathClass().Initialize( this , 1);
34: th1.Start();
35: th2.Start ();
36:
} 37:}
It is not allowed to change the Control
Mainform.textBox1 directly from the thread.
A Control can only be changed by the thread from which it was created. order to still change a control from a thread out, use the method
Invoke () and passes this one
delegate (function pointer) and a parameter array. The actual method (eg updateUIProc () or finish thread ()) is then (in this case) in the thread of the main form. This has also means that neither of the two functions can be executed in parallel several times.