我正在调试一个应用程序,并且在代码中的某个地方,一个线程尝试访问另一个线程创建的列表框。在尝试访问列表框时,应用程序在调试时会引发“跨线程操作无效:控件’ listbox ‘从创建它的线程之外的线程访问”。但是,当我在bin \ Debug文件夹中运行此应用程序的输出时,没有出现异常对话框,并且可以看到从非所有者线程成功访问了列表框,因此这使我认为此处存在行为差异,而不仅仅是抑制的异常。我可以在调试时通过form_load事件中的以下行来跳过此异常
Control.CheckForIllegalCrossThreadCalls = false;
但是,这种不同行为背后的原因是什么?
是的,仅在连接调试器时才检查。这是必要的,因为有 很多 .NET 1.x代码违反了此规则。这不是显而易见的。
更大的问题是这样的代码无法实现。要么靠运气,要么不考虑偶尔出现的绘画问题,或者不认为应用程序死锁时中止应用程序并每天重启一次,这是可以接受的。因为程序员根本没有希望在没有诊断的情况下发现问题。
Microsoft非常关心向后兼容,即使它是错误的兼容也是如此。该修补程序非常出色,即使有时会出错(在不应该检查Show(owner)时也是如此)。有时会忽略检查框架中的代码是否违反了规则。当线程依赖关系是间接的时,会发生这种情况。最常见的情况是在工作线程中更新数据绑定控件的数据源(首先取消绑定!),并使用侦听SystemEvents.UserPreferenceChanged事件的控件(不要在第二个线程上创建UI!)
作为参考,相关的代码位于Control类的静态构造函数中:
static Control() { //... checkForIllegalCrossThreadCalls = Debugger.IsAttached; //... }