非UI线程操作UI
private void button1_Click(object sender, EventArgs e) { new Thread(delegate() { this.label1.Text = "sdfas"; }).Start(); }
如果你开发过Windows Form项目,并使用过多线程操作UI,那么我相信你应该熟悉上面这段代码,在非UI线程操作UI。
当你用F5 debug模式运行此项目,并点击button1运行此段代码时,你将会看到这个异常信息:
但是在我们使用Ctrl+F5或者直接到项目输出目录执行程序,并点击button1的时候,label1的内容被修改成功了,并且没有任何异常被抛出。
这是为什么呢?
一位英文名叫Xiao Liang 来自 MSRA 的工程师告诉我 most Windows native APIs / messages are thread-safe.(在非UI线程操作UI会有潜在的问题,当两个线程在同一时间索取这个控件的话,问题就会油然而生了,呵呵)我们可以在非UI线程操作这个label1. 他还发现, “Control.CheckForIllegalCrossThreadCalls is True with debugger, False without debugger”. OK,主要的原因找到了,关键就是这个Control.CheckForIllegalCrossThreadCalls property.
当有询问Xiao Liang我是否可以把他的这个研究结果公布在我的blog文章里时,他发给我了一片MSDN文章,说这篇文章说得比较清晰:
我读过这篇文章不知道多少遍了,但就是没有注意到下面这段话:
http://msdn.microsoft.com/en-us/library/ms171728.aspx
This exception occurs reliably during debugging and, under some circumstances, at run time. You might see this exception when you debug applications that you wrote with the .NET Framework prior to the .NET Framework version 2.0. You are strongly advised to fix this problem when you see it, but you can disable it by setting the CheckForIllegalCrossThreadCalls property to false. This causes your control to run like it would run under Visual Studio .NET 2003 and the .NET Framework 1.1.
At last, I think I should thanks Xiao Liang at the end of this blog article.
最后,我想在这篇blog文章的末尾再次感谢Xiao Liang。