Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on multithreading multithreading

Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on


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;        }    }}


Threading Model in UI

Please read the Threading Model in UI applications (old VB link is here) in order to understand basic concepts. The link navigates to page that describes the WPF threading model. However, Windows Forms utilizes the same idea.

The UI Thread

  • There is only one thread (UI thread), that is allowed to access System.Windows.Forms.Control and its subclasses members.
  • Attempt to access member of System.Windows.Forms.Control from different thread than UI thread will cause cross-thread exception.
  • Since there is only one thread, all UI operations are queued as work items into that thread:

enter image description here

enter image description here

BeginInvoke and Invoke methods

enter image description here

Invoke

enter image description here

BeginInvoke

enter image description here

Code solution

Read answers on question How to update the GUI from another thread in C#?.For C# 5.0 and .NET 4.5 the recommended solution is here.


You only want to use Invoke or BeginInvoke for the bare minimum piece of work required to change the UI. Your "heavy" method should execute on another thread (e.g. via BackgroundWorker) but then using Control.Invoke/Control.BeginInvoke just to update the UI. That way your UI thread will be free to handle UI events etc.

See my threading article for a WinForms example - although the article was written before BackgroundWorker arrived on the scene, and I'm afraid I haven't updated it in that respect. BackgroundWorker merely simplifies the callback a bit.