C # Operate the control in different threads (the operation between threads is invalid, and the control is accessed from a thread other than the thread that created it)

When writing something recently, you need to operate the control not created by this thread in multiple threads, and an error is reported when you try to call it directly (the operation between threads is invalid, and it is never accessed by the thread that created the control, InvalidOperationException), It can be seen from the query that by default, c # does not allow other threads to directly operate controls not created by it. Then what shall I do? Don't worry. You can learn how to solve this problem through the following example.

text

Let's first look at operating controls in the same thread

Create a simple window with only one textbox and one button.
This window class has a method that aims to add the word test to the text box.

 private void addText() { This.textBox1. Text+=" r  nTest"; }

This method is called in the click event of the button.

 private void button1_Click(object sender, EventArgs e) { this.addText(); }

The actual effect shows that there is no problem in operating the control in the same thread

Let's look at the operation in different threads

The window is the same window. Set a timer to simulate calling the addtext method in different threads
Define the method first.

 private void timerAddText() { System.Timers.Timer t = new System.Timers.Timer(2000); t.Elapsed += new System.Timers.ElapsedEventHandler(callme); t.AutoReset = true; t.Enabled = true; } public void callme(object source,  System.Timers.ElapsedEventArgs e) { addText(); }

Then call the method in the construction method of the form class, that is, add a

 TimerAddText();

An attempt was made to execute, and an error was reported: the inter thread operation was invalid, and the control was accessed from a thread other than the thread that created it, InvalidOperationException。

resolvent

Why do you report an error? To borrow someone else's words:

C # prohibits cross thread direct access to controls. InvokeRequired is created to solve this problem. When the InvokeRequired property value of a control is true, it indicates that a thread other than the thread that created it wants to access it. At this time, it will call new MethodInvoker (LoadGlobalImage) internally to complete the following steps. This practice ensures the security of the control. You can understand it this way. If someone wants to borrow money from you, he can take it directly in your wallet. This is too unsafe, Therefore, you must let others tell you first, and then you can take the money out of your wallet and lend it to others, so it is safe.

So what should we do? Let's first understand the following two things:

InvokeRequired property of control

This is the summary in vs

Gets a value indicating whether the caller must call the Invoke method when making method calls to the control, because the caller is in a thread other than the thread where the control was created.
Return results:
If the System If Windows.Forms.Control.Handle is created on a thread different from the calling thread (indicating that you must call the control through the Invoke method), then it is true; Otherwise, it is false.

Control's invoke method

Function prototype 1

 public object Invoke(Delegate method); //Summary: //Executes the specified delegate on the thread that owns the underlying window handle for this control. //Parameters: //method: //The delegate that contains the method to call in the thread context of the control. //Return results: //The return value of the delegate being called, or null if the delegate has no return value.

Function prototype 2

 public object Invoke(Delegate method, params object[] args); //Summary: //Executes the specified delegate with the specified parameter list on the thread that owns the control's underlying window handle. //Parameters: //method: //A method delegate that takes the same number and type of parameters as those contained in the args parameter. //args: //An array of objects passed as arguments to the specified method. If this method has no parameter, the parameter can be null. //Return results: //System. Object, It contains the return value of the delegate being called; If the delegate does not return a value, it is null.

There is an idea here, that is, when operating the control, the InvokeRequired property is used to determine whether the current thread can directly operate the control. If not (the value is true), Invoke() is used to let the control's parent (the thread that created the control) operate the control.

Add the following line to define a delegate.

 //Define a delegate private delegate void delegateAddText();

Then modify the method body of the timer bound method (call me here) as follows

 public void callme(object source,  System.Timers.ElapsedEventArgs e) { //Judge whether the current process has the right to operate on the space if (textBox1.InvokeRequired) { //Make the control's parent (original thread) execute the delegate through invoke, that is, addtext textBox1.Invoke(new delegateAddText(addText)); } else { //If you have permission to operate, just call it directly addText(); } }

Then try running again, and the problem is solved.

References

1. [Head picture] [Picture] Original black instrument of Huawuyu battlefield
2. [Data] [CSDN] Lnstree C # multithreading problem

Zimiao haunting blog (azimiao. com) All rights reserved. Please note the link when reprinting: https://www.azimiao.com/1531.html
Welcome to the Zimiao haunting blog exchange group: three hundred and thirteen million seven hundred and thirty-two thousand

Comment

*

*

Comment area

  1. bboysoulcn 05-25 15:09 reply

    fabulous