如何找出线程锁定发生的地方?

我们公司的一个Windows Forms应用程序在几个月内出现了一个奇怪的问题。 该应用程序对我们的大多数客户非常可靠,但在某些PC(主要是无线局域网连接)中,应用程序有时只是没有响应。 (你点击界面和Windows让你等待或杀死应用程序)。

我很长一段时间无法找到问题,但现在我知道发生了什么。 该应用程序有这一行代码

// don't blame me for this. Wasn't my code :D
Control.CheckForIllegalCrossThreadCalls = false

并使用一些后台线程来修改控件。

没有,我找到了一种方法来重现应用程序停止我的开发机器上的响应错误,并将其跟踪到实际使用Invoke()在主线程中运行任务的行。

Me.Invoke(MyDelegate, arg1, arg2)

显然有一个线程锁定的地方。 删除后

Control.CheckForIllegalCrossThreadCalls = false

声明并重构整个程序以使用Invoke()(如果从后台线程修改控件),则问题(希望)消失。

但是,我想知道是否有一种方法可以在不调试每行代码的情况下找到这样的错误(即使我在应用程序停止响应后闯入调试器,我也无法知道最后发生了什么,因为IDE没有跳转到Invoke()语句)

换一种说法:

如果我的应用程序挂起,我怎么才能找出哪一行代码最后被执行?

甚至可能在客户PC上。

我知道VS2010提供了一些向后调试功能,也许这将是一个解决方案,但目前我正在使用VS2008。


你很可能正确地识别了罪魁祸首,将CheckForIllegalCrossThreadCalls设置为false是创建随机死锁的好方法。 该属性甚至存在的唯一原因是允许调试borked .NET 1.x程序。

要解决死锁问题,您需要使用Debug + Windows + Threads窗口在各个线程之间切换并查看其调用堆栈。 但考虑到源代码的可能性,这将会很困难,因为它很可能是非托管代码对消息队列或SendMessage()执行某些操作。 你没有编写代码,没有源代码也没有调试符号。 他们也往往是随机的,下一次它的死锁可能看起来完全不同。

Windows基本上是线程不安全的对象。 他们拥有非常大量的国家。 不仅仅在Windows窗体类包装中,也在Windows本身中。 我相信你解决了这个问题。


也许这可能会帮助你:http://www.debuginspector.com/index.htm

这是一个Visual Studio扩展,它允许您追踪死锁,并且它具有一系列用于调试线程的漂亮功能(如查看多线程的调用堆栈而无需转到线程窗口)。


有一个算法来查找死锁。 查看这些谷歌搜索结果:http://www.google.be/search?hl=zh-CN&client=safari&rls=zh-CN&q=deadlock+detection+algorithm&revid=1345706645&sa=X&ei=zqsSTPbmJ4qy0gTvtOWFCg&ved=0CD4Q1QIoAA

链接地址: http://www.djcxy.com/p/46309.html

上一篇: How to find out where a thread lock happened?

下一篇: How to use unicode inside an xpath string? (UnicodeEncodeError)