4

I have main GUI thread with a function XYZ() to do something about GUI. In other thread, if I call XYZ() from handle of main GUI, it display error "Cross-thread operation not valid: Control 'Button00' accessed from a thread other than the thread it was created on."

How should I solve this? I think I need to send a message to GUI thread to do XYZ function. Please help me.

Thanks.

Ankata

Ankata
  • 141
  • 2
  • 3
  • 4

2 Answers2

7

The reason you are getting this error message is because you are trying to update a GUI control from a different thread than the main which is not possible. GUI controls should always be modified on the same thread which was used to create them.

You could use Invoke if InvokeRequired which will marshal the call to the main thread. Here's a nice article.

But probably the easiest solution would be to simply use a BackgroundWorker because this way you no longer need to manual marshal the calls to the GUI thread. This is done automatically:

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) =>
{
    // call the XYZ function
    e.Result = XYZ();
};
worker.RunWorkerCompleted += (sender, e) =>
{
    // use the result of the XYZ function:
    var result = e.Result;
    // Here you can safely manipulate the GUI controls
};
worker.RunWorkerAsync();
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • In my code: function XYZ is do something and process some GUI control and placed on main form class. I tried add your help code into other thead to call XYZ function as mainForm.XYZ(), but it is the same error? – Ankata Nov 21 '10 at 09:44
  • So you will have to split the processing from updating the GUI controls into two separate functions. This way you would use the first function to do the expensive processing in your background worker and when it returns the result you would call your second function to update the GUI. If you don't split them you cannot run it on a different thread because as explained in my answer GUI controls can only be updated on the main thread. – Darin Dimitrov Nov 21 '10 at 09:46
  • However, it is very complex code for processing and update GUI. – Ankata Nov 21 '10 at 09:48
  • I tried add your help code into other thead to call XYZ function as mainForm.XYZ(), but it is the same error? – Ankata Nov 21 '10 at 09:48
  • Based upon the wording of the original question, I suspect that the OP is actually updating the UI within the XYZ() method. If this is the case, calling it from a BackgroundWorker will not resolve the problem as there will still be cross-threading issues. – Martin Robins Nov 21 '10 at 14:03
3

In general GUI in C# can be updated only from the same thread it was created if it isn't the same thread than the value of InvokeRequired is true else it false, if it true you call again the same method, but from the same thread the GUI was created

you should use it like this:

 delegate void valueDelegate(string value);

    private void SetValue(string value)
    {   
        if (someControl.InvokeRequired)
        {
            someControl.Invoke(new valueDelegate(SetValue),value);
        }
        else
        {
            someControl.Text = value;
        }
    }

Try this for additional information

How to update the GUI from another thread in C#?

Community
  • 1
  • 1
Delashmate
  • 2,344
  • 5
  • 26
  • 40
  • Because there are a lot of processes before and after update many controls. So I can not use delegate method. Do you know how to send a message to another thread and it will process by itself – Ankata Nov 21 '10 at 09:57
  • I don't understand why you can't use delegate, are you sure you understand the code above? this code is simply check if you are in the thread that create the control, and if not it call the same method from the rigth thread,that invisiable to you, so the declaration of the delegate it's gust thecnical issue.. – Delashmate Nov 22 '10 at 10:41