When using multiple threads controls on a form cannot be called directly. Doing so will throw an exception like ‘Cross-thread operation not valid: Control ‘dc’ accessed from a thread other than the thread it was created on.’
Fortunately there is a rather simple solution for this problem. Use the Invoke method to execute code in the GUI thread.
The invokemethod has the following prototype
public void Invoke(System.Delegate delegate);
For example: from a worker thread a button on a form (Form1) must be pressed. From inside the thread use the following construct to perform it thread safe.
Invoke((MethodInvoker)delegate { Button1.Click(); });
Invoke is a member of the Control class. To make it work use a control created in the same thread. In the example above you can use Form1.Invoke() or Button1.Invoke() since they both are created in the same thread.
MethodInvoker is a default delegate definition. Its definition is delegate void MethodInvoker;
External delegates:
Of course the delegate can be external as well, sometimes this is favorable to get cleaner code or if the delegate is frequently used.
delegate void ClickTheButton(); void clickTheButton() { ... }
Inside the method
ClickTheButton clickTheButtonDelegate = clickTheButton; Invoke(clickTheButtonDelegate);
Delegates with parameters
Delegates can also be called with parameters . This uses the second form of Invoke()
public void Invoke(System.Delegate delegate, object [] args); void clickTheButton(int value) { ... } delegate void ClickTheButton(int);
Inside the method
ClickTheButton clickTheButtonDelegate = clickTheButton; Invoke(clickTheButtonDelegate, new object[] {1});