Reputation: 3823
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)";
}
}
Upvotes: 3
Views: 2143
Reputation: 1915
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.
Upvotes: 2
Reputation: 81449
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.
Upvotes: 2
Reputation: 122624
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
}
Upvotes: 5
Reputation: 134157
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.
Upvotes: 5