How to: Manipulate Controls from Threads

The BackgroundWorker component replaces and adds functionality to the BeginInvoke method; however, the BeginInvoke method is retained for both backward compatibility and future use, if you choose. For more information, see BackgroundWorker Component Overview.

Multithreading is best suited to running processor-intensive procedures of class modules. Unlike other components, there are issues with directly calling methods in controls from separate threads. Methods that affect controls should be executed only on the thread on which the control was created. Because marshalling calls from one thread and sending them across thread boundaries to another is very expensive in terms of system resources, you should avoid repeatedly making calls to controls on other threads. At best, direct calls from other threads are expensive, and the performance of your application will suffer. At worst, conditions could occur that cause a deadlock in your application, freezing execution.

However, there might be occasions when you want to call methods of controls from your threads. For example, you might call a method that disables a button or updates a display on a form in response to action taken by a thread. The .NET Framework provides methods that are safe to call from any thread for invoking methods that interact with controls owned by other threads. The Invoke method allows for the synchronous execution of methods on controls, whereas the BeginInvoke method initiates asynchronous execution. To use these methods, you must declare a delegate with the same signature as the method you will be invoking. Then you can call the Invoke or BeginInvoke method of any control on the form by supplying the appropriate delegate to the method you want to call. Any required parameters are wrapped in an Object and transmitted to the method.

To invoke methods involving controls owned by other threads

  1. Declare a delegate with a signature identical to the method you want to invoke.

    The following example shows how to declare a delegate with Integer and String parameters.

    Public Delegate Sub myDelegate(ByVal anInteger as Integer, ByVal _
       aString as String)
    
    public delegate void myDelegate(int anInteger, string aString);
    
  2. Use any control to invoke methods that manipulate controls owned by other threads.

    Note

    Parameters (if any) required by the method can be supplied inside an Object.

    • If you want to invoke methods synchronously, call the Control.Invoke Method.

      Label1.Invoke(New myDelegate(AddressOf myMethod), New _
         Object() {1, "This is the string"})
      
      Label1.Invoke(new myDelegate(myMethod), new Object[] {1,
         "This is the string"});
      
    • If you want to invoke methods asynchronously, call the Control.BeginInvoke Method.

      Label1.BeginInvoke(New myDelegate(AddressOf myMethod), _
         New Object() {1, "This is the string"})
      
      Label1.BeginInvoke(new myDelegate(myMethod), new 
      Object[] {1, "This is the string"});
      

See Also

Tasks

Walkthrough: Authoring a Simple Multithreaded Component with Visual Basic

Walkthrough: Authoring a Simple Multithreaded Component with Visual C#

Reference

BackgroundWorker

Concepts

Event-based Asynchronous Pattern Overview

Other Resources

Multithreading in Components