I have a scenario. (Windows Forms, C#, .NET)
UserControl_Load
method the UI become nonresponsive for the duration for load method execution.The pseudocode would look like this:
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. } }
The Exception it gave was
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.
To know more about this I did some googling and a suggestion came up like using 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 seems I'm back to square one. The Application again become nonresponsive. It seems to be due to the execution of line #1 if condition. The loading task is again done by the parent thread and not the third that I spawned.
I don't know whether I perceived this right or wrong. I'm new to threading.
How do I resolve this and also what is the effect of execution of Line#1 if block?
The situation is this: I want to load data into a global variable based on the value of a control. I don't want to change the value of a control from the child thread. I'm not going to do it ever from a child thread.
So only accessing the value so that the corresponding data can be fetched from the database.
In the first line we get to know whether the control we want to access is created on the same thread or another thread. If it's created on another thread then it will execute the second line.
Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on. public: property bool InvokeRequired { bool get(); }; C# Copy.
What Is Cross Threading? Cross threading is the term used when a male threaded fastener, such as a Stainless Steel Machine Screw, does not engage correctly with its female threaded mating partner, such as a Hexagon Nut, and jams.
Invoke(DispatcherPriority, TimeSpan, Delegate, Object) Executes the specified delegate at the specified priority with the specified argument synchronously on the thread the Dispatcher is associated with. Invoke(DispatcherPriority, Delegate, Object, Object[])
As per Prerak K's update comment (since deleted):
I guess I have not presented the question properly.
Situation is this: I want to load data into a global variable based on the value of a control. I don't want to change the value of a control from the child thread. I'm not going to do it ever from a child thread.
So only accessing the value so that corresponding data can be fetched from the database.
The solution you want then should look like:
UserContrl1_LOadDataMethod() { string name = ""; if(textbox1.InvokeRequired) { textbox1.Invoke(new MethodInvoker(delegate { name = textbox1.text; })); } if(name == "MyName") { // do whatever } }
Do your serious processing in the separate thread before you attempt to switch back to the control's thread. For example:
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; } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With