Usage of Invoke in C # --------- Multi-threaded operation: The inter-thread operation is invalid, and it is never accessed by the thread that did not create the control

Design an interface, change the value of the label after clicking the button.
Realization: Click the button to execute the click event of the button, create a thread change under the function, and then execute the method of changing the label in this thread ChangeLabel ();
Insert picture description here
Description: The control is in the UI Created in the main thread, when entering the event response function of the control, it is in the thread of the control, not the main thread. Changing the state of the control in the control's event response function may cause a thread conflict with the main thread.
If you directly use the following wording, you will inevitably make mistakes:

 private void btnChange_Click(object sender, EventArgs e)
 {
     Thread Change = new Thread(new ThreadStart(ChangeLabel));
     Change.Name = "zyh";
     Change.Start();
 }
 private void ChangeLabel()
 {
     try
     {
         label.Text = "改变值";
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message,"错误提示",MessageBoxButtons.YesNo,MessageBoxIcon.Error);
     }
 }

Insert picture description here

Solution:

The correct way is to call the Invoke method of the control in the control response function. The Invoke method will search up the control until it finds the thread that created the control (usually the main thread), and then enter that thread to change the appearance of the control to ensure that no thread conflicts occur. There are three examples of correct writing:

The first:

this.Invoke(new Action(() =>
{label.Text = “关闭”; }
));

The second kind:

this.Invoke(new Action(
delegate { label.Text = “关闭”; }
));

The third kind:

When the InvokeRequired property value of a control is true, it means that a thread other than creating it wants to access it.
MSDN says:
Get a value indicating whether the caller must call the Invoke method when making a method call on the control The side is in a thread other than the thread where the control is created. If the handle of the control is created on a different thread from the calling thread (indicating that you must call the control through the Invoke method), then true; otherwise, false. Controls in Windows Forms are bound to specific threads and do not have thread safety. Therefore, if you call the control 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.

private void ChangeLabel()
{
try
{
    if (label.InvokeRequired)
    {
        label.Invoke(new MethodInvoker(ChangeLabel));
    }
    else
    {
        label.Text = "改变值";
    }
}
catch (Exception ex)
{
    MessageBox.Show(ex.Message,"错误提示",MessageBoxButtons.YesNo,MessageBoxIcon.Error);
}
}

Program execution:
Click the button, the system determines that a thread other than the label thread wants to access it. At this time, the InvokeRequired attribute is true, call the Invoke method, execute the ChangeLabel () method, jump into the else, and execute the change of the label At this time, it succeeded.
Insert picture description here
Simply put, if there are two threads, Thread A and Thread B, and there is a Control c, which is new in Thread A. Then any method called c.InvokeRequired running in Thread A will return false.
Conversely, if any method running in Thread B calls c.InvokeRequired it will return true.
Whether it is a UI thread has nothing to do with the result. (Usually the thread where Control is located is a UI thread, but there can be exceptions)
Insert picture description here
Refer to the blog post:
https://www.cnblogs.com/vaevvaev/p/6909042.html

Published 18 original articles · praised 0 · visits 233

Guess you like

Origin blog.csdn.net/qq_39217004/article/details/105496169