[C# learning how to call Winform[to multi thread

Recommended for you: Get network issues from WhatsUp Gold. Not end users.


  I have a WinForm program for updating the main window thread (worker thread), but the document does suggest that I cannot in multithreaded call this form (why?) But in fact, I call procedures often collapse. How to ask the method from the multi thread in form.?  


  Each derived from the Control class in the WinForm class (class Control) depend on the underlying Windows message pump cycle (message pump loop) to execute. The message loop must have a corresponding thread, because is sent to a window message will actually be sent to create the window thread. As a result, even provides synchronization (synchronization), you can't from multiple threads calling these message processing. Most of the plumbing is hidden, because WinForm is using a proxy (delegate) messages to be bound to the event handling method. The WinForm Windows message into an agent based event, but you still must pay attention to, because of the initial message loop's sake, only to create the form thread to invoke the event handling method. If you call your own thread in these methods, they will deal with events in the thread, but not in the specified thread processing. You can get from any thread calls not belonging to any message processing method.

  The Control class (and its derived classes) to achieve a defined interface -- ISynchronizeInvoke in the System.ComponentModel namespace, and in order to handle the call in multi thread message processing method problem:

public interface ISynchronizeInvoke


 object Invoke(Delegate method,object[] args);

 IAsyncResult BeginInvoke(Delegate method,object[] args);

 object EndInvoke(IAsyncResult result);

 bool InvokeRequired {get;}


  ISynchronizeInvoke provides a standard mechanism for method calls in other threads. For example, if an object implementing the ISynchronizeInvoke, then the thread T1 client can call ISynchronizeInvoke on the object in the Invoke () method. Invoke()Method will block (block) of the thread's call, it will call the package (Marshal) to T2, and the implementation of call in T2, then the return value will be sent to T1, and then returned to the T1 client. Invoke()For an agent to positioning calls this method in T2, and with a regular array of objects as parameters.

  The caller can also check the InvokeRequired property, because you can be in the same thread calls ISynchronizeInvoke can also be re positioning (redirect) to other threads. If the return value of InvokeRequired is false, then the caller can directly call the object.

  For example, suppose you want to call from another thread in the Close method of a form, then you can use the predefined MethodInvoker agent, and calling the Invoke method:

Form form;

/* obtain a reference to the form, 

then: */

ISynchronizeInvoke synchronizer;

synchronizer = form;



MethodInvoker invoker = new 






  ISynchronizeInvoke is not only used in WinForm. For example, a Calculator class provides the sum of the two numbers (Add) method, which is realized through ISynchronizeInvoke. The user must determine the ISynchronizeInvoke.Invoke () method call is executed in the right in a thread.

  C# Write the call on the right thread

  A list of A. Calculator Add () method for adding two numbers. If the user directly call Add () method, it executes the call in the user thread, and the user can through the ISynchronizeInvoke.Invoke () will call to write the correct thread.

  List A:

public class Calculator : ISynchronizeInvoke


 public int Add(int arg1,int arg2)


  int threadID = Thread.CurrentThread.GetHashCode();

  Trace.WriteLine( "Calculator thread ID is " + threadID.ToString());

  return arg1 + arg2;


 //ISynchronizeInvoke implementation 

 public object Invoke(Delegate method,object[] args)


  public IAsyncResult BeginInvoke(Delegate method,object[] args)


   public object EndInvoke(IAsyncResult result)


    public bool InvokeRequired




   //Client-side code

   public delegate int AddDelegate(int arg1,int arg2);

    int threadID = Thread.CurrentThread.GetHashCode();

    Trace.WriteLine("Client thread ID is " + threadID.ToString());

    Calculator calc;

    /* Some code to initialize calc */

    AddDelegate addDelegate = new AddDelegate(calc.Add);

    object[] arr = new object[2];

    arr[0] = 3;

    arr[1] = 4;

    int sum = 0;

    sum = (int) calc.Invoke(addDelegate,arr);

    Debug.Assert(sum ==7);

    /* Possible output:

    Calculator thread ID is 29

    Client thread ID is 30 


  You may not want to synchronize call, because it was packaged and sent to another thread to. You can through the BeginInvoke () and EndInvoke () method to achieve it. You can be in accordance with the general.NET asynchronous programming model (asynchronous programming model) to use these methods: use BeginInvoke () to send the call, EndInvoke () to implement wait for prompt and collect or return results when completed.

  Also worth mentioning is the ISynchronizeInvoke method is not type safe. Type mismatch will result in the execution when the exception is thrown, not a compilation error. So in the use of ISynchronizeInvoke should be extra attention, because the editor cannot check out execution error.

  Implementation of ISynchronizeInvoke requires you to use a proxy to the late binding (late binding) dynamic method invocation. Each agent types are provided by DynamicInvoke () method: public object DynamicInvoke(object[] 


  In theory, you must will be acting a method in a need to provide thread real object running in, and the Invoke () and BeginInvoke () calls the DynamicInvoke method in the proxy () method. The implementation of ISynchronizeInvoke is a non - with the general programming skills, the accompanying source file contains an Synchronizer helper class (helper class) and a test program, the test program is used to demonstrate the lists in A Calculator is how to use the Synchronizer class to achieve ISynchronizeInvoke. Synchronizer is a common implementation of ISynchronizeInvoke, you can use the derived class of it or its itself as an object for use, and the ISynchronizeInvoke assigned to it.  

  To an important element of Synchronizer is to use a WorkerThread nested class(nested class). There is a project in WorkerThread (work item) query. Contains the methods and parameters of WorkItem class agent. Invoke()And BeginInvoke () used to be a work item instance is added to the query. WorkerThread.NET of a new worker thread, which is responsible for monitoring the work item query task. After the query to the project, the worker will read them, and then call DynamicInvoke () method.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Posted by Diana at November 17, 2013 - 5:25 AM