Problem
I have a scenario in mind. (.NET Framework, Windows Forms)
This is how the pseudocode might look:
CODE 1
UserContrl1_LoadDataMethod()
{
if (textbox1.text == "MyName") // This gives exception
{
//Load data corresponding to "MyName".
//Populate a globale variable List<string> which will be binded to grid at some later stage.
}
}
It made an exception in this case.
To learn more about this, I performed some research and found a suggestion to use the following code.
CODE 2
UserContrl1_LoadDataMethod()
{
if (InvokeRequired) // Line #1
{
this.Invoke(new MethodInvoker(UserContrl1_LoadDataMethod));
return;
}
if (textbox1.text == "MyName") // Now it wont give an exception
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be binded to grid at some later stage
}
}
BUT BUT BUT… it appears that I’ve returned to square one. The application has been unresponsive once more. The execution of line #1’s if condition appears to be the cause. The parent thread, not the third that I spawned, is in charge of loading.
I’m not sure if my perception was correct or not. I’m a newbie when it comes to threading.
What is the consequence of executing Line#1 if block and how can I resolve this?
The situation is as follows: I’d like to load data into a global variable based on a control’s value. I don’t want the child thread to modify the value of a control. I’m not going to do it from a kid’s thread again.
As a result, the value is only accessed so that the corresponding data may be retrieved from the database.
Asked by Prerak K
Solution #1
According to Prerak K’s (now-deleted) update comment:
The following is an example of the solution you’re looking for:
UserContrl1_LOadDataMethod()
{
string name = "";
if(textbox1.InvokeRequired)
{
textbox1.Invoke(new MethodInvoker(delegate { name = textbox1.text; }));
}
if(name == "MyName")
{
// do whatever
}
}
Before attempting to return to the control thread, do your important processing in a different thread. Consider the following scenario:
UserContrl1_LOadDataMethod()
{
if(textbox1.text=="MyName") //<<======Now it wont give exception**
{
//Load data correspondin to "MyName"
//Populate a globale variable List<string> which will be
//bound to grid at some later stage
if(InvokeRequired)
{
// after we've done all the processing,
this.Invoke(new MethodInvoker(delegate {
// load the control with the appropriate data
}));
return;
}
}
}
Answered by Jeff Hubbard
Solution #2
Please read the Threading Model in UI Applications (old VB link here) to get a better understanding of the fundamental concepts. The link takes you to a website that explains WPF’s threading paradigm. Windows Forms, on the other hand, uses the similar concept.
Read the responses to the question. In C#, how can I update the GUI from another thread? The recommended solution for C# 5.0 and.NET 4.5 may be found here.
Answered by Ryszard Dżegan
Solution #3
Invoke or BeginInvoke should only be used for the bare minimum of effort required to modify the UI. Your “heavy” function should run on an other thread (e.g., via BackgroundWorker), but Control should be used thereafter. Invoke/Control. BeginInvoke just to update the UI. That way your UI thread will be free to handle UI events etc.
A WinForms example can be found in my threading article, albeit it was written before BackgroundWorker was introduced, and I’m afraid I haven’t updated it in that regard. BackgroundWorker just makes the callback a little easier.
Answered by Jon Skeet
Solution #4
It’s too late now, I realize. However, if you’re having problems accessing cross thread controls today, you’re not alone. This is the shortest response so far:P
Invoke(new Action(() =>
{
label1.Text = "WooHoo!!!";
}));
This is how I use a thread to access any form control.
Answered by Bravo
Solution #5
I had this issue with the FileSystemWatcher and discovered that the following code fixed it:
fsw.SynchronizingObject = this
The control will then deal with the events using the current form object, and will thus be on the same thread.
Answered by Peter C
Post is based on https://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the