Tutorial :Help needed for 'cross-thread operation error' in C#



Question:

In the following code MessageReceived is on a different thread to label1 and when trying to access it I will get this error:

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

foo.MessageReceived += new Agent.MessageReceivedHandler(foo_MessageReceived);     void foo_MessageReceived(Message message)  {     label1.Text = message.Body;  }      

How can I solve this?

More: apparently I need to use delegate and invoke, but I don't know how, can you please explain in more detail?


Solution:1

Make always sure you update your GUI on the main thread (GUI thread).

foo.MessageReceived += new Agent.MessageReceivedHandler(foo_MessageReceived);

public delegate void MyDelegate(Message msg);  void foo_MessageReceived(Message message)  {      if (InvokeRequired)     {        BeginInvoke(new MyDelegate(foo_MessageReceived),new object[]{message});     }     else     {        label1.Text = message.Body;     }  }  


Solution:2

Hopefully this will be closed as an exact duplicate, but if not:

Don't touch the GUI from a non-GUI thread. Use BackgroundWorker and report progress appropriately, or read the WinForms page of my threading article for more direct control (Control.Invoke/BeginInvoke).


Solution:3

Delegate updating the label to the thread that created the label instead of trying to update it directly.


Solution:4

You need to use Control.Invoke (or Control.BeginInvoke). First, create a new Windows Forms application and add a label and a button. Double click on the button in Visual Studio to edit it's Click event and add the following code:

    private void button1_Click(object sender, EventArgs e)      {          new System.Threading.Thread(new System.Threading.ThreadStart(Run)).Start();      }        void Run()      {          label1.Invoke(new Action(delegate()          {              label1.Text = System.Threading.Thread.CurrentThread.Name + " " + System.DateTime.Now.ToString();          }));      }  


Solution:5

This is totally not helpful. I wish I could vote myself down.

I may be out of date, but from what I remember you aren't allowed to alter anything in the GUI from anything but the main thread.


Solution:6

In your Agent class, when you raise the MessageReceived event, you'll have to check whether the Target of the event-handler implements ISynchronizeInvoke. If it does, and if the InvokeRequired property returns true, you'll have to invoke the eventhandler.

If you're not using WinForms, but WPF, you cannot rely anymore on ISynchronizeInvoke since the WPF controls do not implement that interface. Instead, you'll have to work with AsyncOperation and AsyncOperatoinManager.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »