From:http://www.th7.cn/program/net/201306/140033.shtml
Controls in Windows forms are bound to a specific thread and do not have thread safety. Therefore, if you invoke a control's method from another thread, you must use an Invoke method of the control to marshal the call to the appropriate thread. This property can be used to determine whether the Invoke method must be called, which is useful when you do not know what thread owns the control.
If you have already created a handle to the control, there are four methods on the control that can be safely called from any thread except the InvokeRequired property, which are: Invoke, BeginInvoke, EndInvoke, and CreateGraphics. Calling CreateGraphics before creating a handle on a background thread may result in an illegal cross-thread call. For all other method calls, you should use one of these invoke methods when making calls from another thread.
If the control handle does not already exist, InvokeRequired searches along the control's parent chain until it finds a control or form that has a window handle. If the appropriate handle cannot be found, the InvokeRequired method returns false.
This means that if you do not need invoke (the call occurs on the same thread), or if the control is a handle created on another thread but has not yet created the control, invokerequired can return false.
If you have not yet created a handle to the control, you cannot simply invoke the property, method, or event on the control. This can cause the control's handle to be created on a background thread, thereby isolating the control on the thread without the message pump and making the application unstable.
When InvokeRequired returns false on a background thread, you can also avoid this by checking the value of ishandlecreated. If a control handle has not been created, you must wait until the control handle has been created to invoke invoke or BeginInvoke. Typically, only when a background thread is created in the constructor of the application main form (as in Application.Run (new MainForm)), before the form is displayed or Application.Run is canceled. This is the only scenario that can happen.
One solution is to wait until you have created a handle to the form, and then start the background thread. Force the creation of a handle by calling the Handle property, or wait for the Load event to start the background process.
A better solution would be to use the SynchronizationContext returned by SynchronizationContext instead of using controls for inter-thread marshaling. --msdn
An easier explanation and example for this (see links: About InvokeRequired and Invoke):
And about InvokeRequired and invoke is a commonplace problem, the general standard notation ( image from:avoiding invokerequired, the same as below):
The advantage of this approach is that it works well on. NET 1.0+, but if there are many controls, there is a lot of code (lots of defining delegates).
On. NET 2.0, you can use anonymous delegates andMethodInvoker,简化代码写法,关于MethodInvokerMSDN上的定义如下:
MethodInvoker provides a simple delegate that is used to invoke a method with a list of void arguments. You can use this delegate when invoking a control 's Invoke method or when you need a simple delegate and do not want to define it yourself.
Or a more concise notation:
While the. NET 3.5+ can take advantage of its features, the code is as follows ( come in:A Generic Method for cross-thread Winforms Access)
Resources:
About InvokeRequired and invoke
Avoiding invokerequired
A Generic Method for Cross-thread Winforms Access
About InvokeRequired and invoke