为什么没有检测到非法交叉线程?

时间:2011-10-18 20:38:08

标签: .net winforms

所有

我创建了一个Windows窗体和一个Button。在另一个线程中,我尝试更改按钮的文本,然后崩溃;但如果我试图改变按钮的颜色,它可靠地成功。我认为如果您更改了任何Windows窗体控件属性,它将崩溃。有人能告诉我发生了什么事吗?

这是我的代码,在注释掉的行上没有崩溃(但我认为应该):

Thread thr = new Thread(() => { 
    //myButton.ForeColor = Color.Purple; // this never causes a crash :=(
    myButton.Text = Color.Purple.ToString(); // this always causes a crash.
}); // 
thr.Start();

任何见解都将不胜感激!

迈克尔

3 个答案:

答案 0 :(得分:6)

Control.ForeColor属性setter调用Invalidate()方法。这在Windows中是线程安全的。它只是在内部窗口状态中设置“此窗口需要重新绘制”状态位。直到稍后,当Paint事件运行时,窗口才会实际发生任何事情。在UI线程上。

Winforms包含用于抑制异常的显式代码。

其他示例是读取Text属性(不写入)。还有记录的,InvokeRequired,BeginInvoke,EndInvoke,Invoke和CreateGraphics。就是这样。

答案 1 :(得分:0)

  

它可靠地成功

不要把你的运气推得太远。它迟早会崩溃。始终在GUI线程上执行修改。

答案 2 :(得分:0)

Documentation说:

  

在不使用Invoke方法的情况下,从创建控件的线程以外的线程调用控件是不安全的。

在没有先看的情况下穿过街道是不安全的。你不会总是受到汽车的撞击,但是你的机会很高。

  

在调试期间以及在某些情况下在运行时可靠地发生此异常。调试在.NET Framework 2.0之前使用.NET Framework编写的应用程序时,可能会看到此异常。强烈建议您在看到此问题时解决此问题,但可以通过将CheckForIllegalCrossThreadCalls属性设置为false来禁用它。