为什么这不起作用?
程序停在: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)";
}
}
答案 0 :(得分:5)
在Windows中,控件只能由创建它的线程更新。您需要使用Control.Invoke
来对UI线程进行方法调用以更新文本。
MSDN Control.Invoke页面上有一个示例。
答案 1 :(得分:5)
从后台线程执行这些操作时,您需要使用Control.Invoke
:
private void ThreadProcUnsafe()
{
while (true)
{
Thread.Sleep(2000);
textBox1.Invoke(new Action(() =>
{
textBox1.Text = "(New Text)";
}));
}
}
如果您正在编写可能从后台线程运行的通用代码,您还可以检查Control.InvokeRequired
属性,如:
if (textBox1.InvokeRequired)
{
textBox1.Invoke(...);
}
else
{
// Original code here
}
答案 2 :(得分:2)
不允许跨线程访问Windows控件。您需要另一种不那么直接的机制,例如事件或消息传递。
关于Control.Invoke问题的Here's an article以及为什么BeginInvoke是更好的选择,因为死锁机会更少。
答案 3 :(得分:2)
虽然我建议使用Invoke
或BeginInvoke
(当然在调用InvokeRequired
之后),但您可以通过从Form或UserControl中调用它来完全阻止跨线程异常:
CheckForIllegalCrossThreadCalls = false;
(CheckForIllegalCrossThreadCalls
是Control
)的静态属性
如果您选择这样做,可能会在您的用户界面中获得一些奇怪的结果。