4

How can I access a control from a thread other than the thread it was created on, avoiding the cross-thread error?

Here is my sample code for this:

private void Form1_Load(object sender, EventArgs e)
{
    Thread t = new Thread(foo);
    t.Start();
}

private  void foo()
{
    this.Text = "Test";
}
Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
Thorin Oakenshield
  • 14,232
  • 33
  • 106
  • 146
  • 2
    There are lots of questions on Stack Overflow about this. – ChrisF Mar 09 '11 at 08:58
  • If you are new to Winforms I suggest start with WPF. Many might disagree but imho Winforms is dead. In WPF this issue was solved by queuing operations to each component. – Gilad Mar 09 '11 at 09:07
  • Dupe of http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the-t http://stackoverflow.com/questions/3650109/cross-thread-operation-not-valid-control-textbox1-accessed-any-help-plz http://stackoverflow.com/questions/1809864/how-to-access-a-form-control-from-system-timers-timer-cross-thread-problem – gideon Mar 09 '11 at 14:40
  • Lots of potential duplicates, not a single close vote. – Robert Harvey Mar 10 '11 at 03:35

4 Answers4

14

There's a well known little pattern for this and it looks like this:

public void SetText(string text) 
{
    if (this.InvokeRequired) 
    {
        this.Invoke(new Action<string>(SetText), text);
    }
    else 
    { 
        this.Text = text;
    }
}

And there's also the quick dirty fix which I don't recommend using other than to test it.

Form.CheckForIllegalCrossThreadCalls = false;
John Leidegren
  • 59,920
  • 20
  • 131
  • 152
  • Correct answer, except that the pattern is imho well known :) – Frederik Gheysels Mar 09 '11 at 09:00
  • Let's swap those words then, becuase I didn't mean it in the sense of unknown, just the "little pattern" part. – John Leidegren Mar 09 '11 at 09:03
  • `Form.CheckForIllegalCrossThreadCalls = false;` - this is exactly what I needed. I just have a few counters to set from the background thread. Nothing logically important, just to show on the screen. I do not care about race conditions... THANKS! – vt100 Mar 08 '19 at 15:13
2

You should check for the Invoke method.

Shimrod
  • 3,115
  • 2
  • 36
  • 56
2

You should check with InvokeRequired method to see if you are on the same thread or a different thread.

MSDN Reference: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.invokerequired.aspx

Your method can be refactored this way

private void foo() {
    if (this.InvokeRequired)
        this.Invoke(new MethodInvoker(this.foo));
   else
        this.Text = "Test";       
}
llusetti
  • 53
  • 5
1

Check - How to: Make Thread-Safe Calls to Windows Forms Controls

private  void foo()
{
    if (this.InvokeRequired)
    {   
        this.Invoke(() => this.Text = text);
    }
    else
    {
        this.Text = text;
    }
}
Unmesh Kondolikar
  • 9,256
  • 4
  • 38
  • 51