Jür*_*ock 7 .net thread-safety winforms
我们公司的一个Windows Forms应用程序在几个月内出现了一个奇怪的问题.该应用程序对我们的大多数客户非常可靠,但在一些PC(主要是无线局域网连接)上,应用程序有时只是没有响应.(您单击UI和窗口会要求您等待或终止该应用程序).
我无法长时间追踪这个问题,但现在我想出了发生了什么.该应用程序有这行代码
// don't blame me for this. Wasn't my code :D
Control.CheckForIllegalCrossThreadCalls = false
Run Code Online (Sandbox Code Playgroud)
并使用一些后台线程来修改控件.
不,我找到了一种方法来重现应用程序停止响应我的开发机器上的错误并将其跟踪到我实际上使用Invoke()在主线程中运行任务的行.
Me.Invoke(MyDelegate, arg1, arg2)
Run Code Online (Sandbox Code Playgroud)
显然有一个线程锁定.删除后
Control.CheckForIllegalCrossThreadCalls = false
Run Code Online (Sandbox Code Playgroud)
语句和重构整个程序使用Invoke()如果从后台线程修改控件,问题(希望)已经消失.
但是,我想知道是否有办法找到这样的错误而不调试每一行代码(即使我在应用程序停止响应后进入调试器我也无法告诉最后发生了什么,因为IDE没有跳转到Invoke()语句)
换一种说法:
如果我的应用程序挂起,我怎么能弄清楚最后执行了哪行代码?
甚至可能在客户PC上.
我知道VS2010提供了一些向后调试功能,也许这将是一个解决方案,但目前我正在使用VS2008.
您很可能正确地识别出了罪魁祸首,将 CheckForIllegalCrossThreadCalls 设置为 false 是创建随机死锁的好方法。该属性存在的唯一原因是允许调试无效的 .NET 1.x 程序。
要解决死锁问题,您需要使用“调试”+“Windows”+“线程”窗口在各个线程之间切换并查看它们的调用堆栈。但考虑到源的可能性质,这将很困难,因为很可能是非托管代码对消息队列或 SendMessage() 执行某些操作。您没有编写的代码,也没有源代码或调试符号。它们也往往是随机的,下次死锁可能看起来完全不同。
Windows 本质上是线程不安全的对象。它们有大量与之相关的状态。不仅在 Windows 窗体类包装器中,在 Windows 本身内部也是如此。我相信你已经解决了问题。