tags:

views:

61

answers:

4
+1  Q: 

TextBox and Thread

Why doesn't this work?

The program stops on: this.textBox1.Text = "(New text)";

 Thread demoThread;
 private void Form1_Load(object sender, EventArgs e)
 {
     this.demoThread = new Thread(new ThreadStart(this.ThreadProcUnsafe));
     this.demoThread.Start();

     textBox1.Text = "Written by the main thread.";
 }

 private void ThreadProcUnsafe()
 {
     while (true)
     {
         Thread.Sleep(2000);
         this.textBox1.Text = "(New text)";           
     }
 }
+4  A: 

In windows, a control may only be updated by the thread that created it. You need to use Control.Invoke to marshall a method call to the UI thread to update the text.

There is an example of this on the MSDN Control.Invoke page.

Justin Ethier
You can use the this.InvokeRequired method to see if the thread that is executing is the UI thread. If .InvokeRequired is false you can safely update the .Text property of the control.
TLiebe
Absolutely - but in his example it is required.
Justin Ethier
+2  A: 

You need to use Control.Invoke when performing these operations from a background thread:

private void ThreadProcUnsafe()
{
    while (true)
    {
        Thread.Sleep(2000);
        textBox1.Invoke(new Action(() =>
        {
            textBox1.Text = "(New Text)";
        }));
    }
}

If you are writing generic code that may be run from a background thread, you can also check the Control.InvokeRequired property, as in:

if (textBox1.InvokeRequired)
{
    textBox1.Invoke(...);
}
else
{
    // Original code here
}
Aaronaught
A: 

Cross-thread access to Windows controls is not allowed. You need another, less direct mechanism such as event or message passing.

Here's an article on the Control.Invoke issue and why BeginInvoke is a better choice due to less chance of deadlock.

Paul Sasik
A: 

Although I recommend using Invoke or BeginInvoke (after calling InvokeRequired of course), you can prevent the cross-thread exception altogether by calling this from your Form or UserControl:

CheckForIllegalCrossThreadCalls = false;

(CheckForIllegalCrossThreadCalls is a static property of Control)

If you choose to do this, you may get some weird-looking results in your UI.

fre0n