Invalid cross-thread operation: the control' XXX' was accessed from a thread other than the one that created it.
Yes. NET Framework provides methods that can be safely called from any thread to call methods that interact with controls owned by other threads.
The Invoke method allows synchronous execution of methods on the control, while the BeginInvoke method initializes asynchronous execution. To use these methods, the delegate must be declared with the same signature as the method to be called. Then, you can call the Invoke or BeginInvoke method of any control on the form by providing the appropriate delegate to the method to be called. Any required parameters are wrapped in an object and passed to the method.
Calling a method involving a control owned by another thread declares a delegate with the same signature as the method to be called.
Public delegate void myDelegate(int anInteger, String String);
Use any control to call methods that operate on controls owned by other threads. Note: The parameters required by the method (if any) can be provided in the object.
Label 1。 Invoke(new myDelegate(myMethod), new Object[] {1, "This is a string"});
If you want to call the method asynchronously, call the control. BeginInvoke method.
Label 1。 Begin invoke (new my delegate (my method), new Object[] {1, "This is a string"});
For example, create a new Windows application project Win 1, add a button named button 1 to the form Form 1, then go to the code page and modify the code as follows.
Use the system;
Use the system. Windows . Forms
Namespace win 1
{
Public partial classes Form 1: Form
{
Public delegate void my delegate (); //Declare delegation
Public Form 1 ()
{
initialize component();
}
PrivateVoidButton1_ click (object sender, eventargs e)///Double-click Button 1 here to generate code and automatically create an event delegate.
{
New system. Threading.thread (new system. Thread. Thread start). start(); //Create a new thread and start it.
}
Public void setting text ()
{
Button 1. Text = "Hello";
}
Public void new thread ()
{
System. Thread. Thread. Sleep (2000); //Thread sleeps for 2 seconds.
Button 1. BeginInvoke (new my proxy (set text)); //Execute "Set Text" on the thread where button 1 is located.
}
}
}
Run: Click the button 1, and the text will change after two seconds.
What are the purposes of Invoke and BeginInvoke, and how are they realized internally?
These two methods are mainly to let the given method be executed on the thread created by the control.
Invoke uses SendMessage of Win32API,
BeginInvoke uses PostMessage of Win32API.
These two methods put the message into the message queue of the UI thread. When the UI thread processes this message, it will execute the incoming method in its own context. In other words, all threads that use BeginInvoke and Invoke are executed in the UI main thread, so if some static variables are involved in these methods, there is no need to consider locks.
Does each thread have a message queue?
No, only the thread that creates the form object will have a message queue (the description of this paragraph is given below).
When a thread is first established, the system assumes that the thread will not be used for any user-related tasks. This can reduce the thread's demand for system resources. However, once a thread calls a function related to the graphical user interface (such as checking its message queue or creating a window), the system will allocate some extra resources to the thread so that it can perform tasks related to the user interface. In particular, the system allocates a T H R E A D I N F O structure and associates the data structure with the thread.
This structure of T H R E A D I N F O contains a set of member variables, with which a thread can think that it is running in its own exclusive environment. T H R E A D I N F O is an internal and unpublished data structure. Used to specify the thread's registered message queue (delivery message queue), send message queue, reply message queue (reply message queue), virtualized input queue, wake-up flag and several variables used to describe the thread's local input state. Figure 2 6- 1 describes the structure of T H R E A D I N F O and three related threads.