我正在使用VS 2012.任何人都可以给出一个简单的例子,为什么我在使用其他线程时需要control.Invoke / BeginInvoke。 我试图通过其他线程更改文本框上的文本,但一切正常。我知道在这种情况下,必须从gui线程调用更改。 但是当我从线程中找不到某些东西时,我找不到例子。 谢谢。 Liron
例如:我有这个代码,但它运行正常:
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(new ThreadStart(ChangeText));
t.Start();
}
private void ChangeText()
{
for (int i = 0; i < 50; ++i)
{
textBox1.Text += "a";
Thread.Sleep(100);
}
}
答案 0 :(得分:2)
好的,使用您的示例代码,假设您的用户界面中有一个按钮,当点击该按钮时,会检查textBox1.Text
,如果它是&#34; aaaaa&#34;,则更改文本去花生酱!&#34;假设文本是&#34; aaaaa&#34;在textBox1.Text
中调用get
ChangeText
方法后,您偶然会点击该按钮。在GUI线程上,您读取textBox1.Text
的当前值,您发现该属性等于&#34; aaaaa&#34;,您将textBox1.Text
设置为&#34;花生酱!& #34;和ChangeText
(在后台线程上)调用textBox1.Text
&#39; set
方法将其更新为&#34; aaaaaa&#34;。 应该发生的是文本被设置为&#34;花生酱!a&#34;,但它好像你从未改变GUI线程中的任何内容。发生这种情况是因为后台和前台线程完成的工作是交错的。这称为竞争条件,可以通过调用Invoke
或BeginInvoke
来避免它,以确保只有一个线程同时访问/变更数据。
您在代码中很少看到此类问题的原因是计算机非常快,并且在恰当的时间点击此类错误的可能性非常低。一般来说,竞争激烈的线程越多,你就越有可能看到竞争条件导致问题。