我的应用程序在调用lock ( obj )
时无限期地阻塞,但线程窗口中没有其他线程可以根据需要进行任何代码浏览。是不是有必要涉及另一个线程?它为什么不出现,它可能是什么原因导致它出现?
更新:我想我弄明白是什么导致了它。我有这种hackish阻止,我Wait()
在ManualResetEvent
内锁两个锁。问题是我需要在等待之前释放这些锁,以便其他线程可以使用它们,所以我做的是这样的:
lock ( one ) {
lock ( two ) {
...
Monitor.Exit( two );
Monitor.Exit( one );
syncEvent.Wait();
Monitor.Enter( one );
Monitor.Enter( two );
}
}
我不指望的是Monitor.Exit()
实际上只递减内部递归计数器,并且可能从已经同步的块调用该方法;因此锁实际上并未发布。
我想从一开始就是一个坏主意。我刚刚把这个电话移到锁定区块之外的Wait()
,现在看起来工作正常。
感谢您的见解。
虽然,现在我考虑一下,如果从其中一个锁上的代码同步调用该方法,则在调用Wait
时仍然不会释放该方法。因此,我必须小心,永远不要从同步块中调用它,我想。
答案 0 :(得分:6)
线程窗口中没有其他线程可以使用任何代码进行浏览
我向你保证那些其他线程正在运行代码。无论您的机器上是否有源代码,这些线程都无关紧要。
是否有必要涉及另一个线程?
是。
为什么不出现,以及可能是什么原因导致它无法出现?
也许拿出锁的线程已经进入睡眠状态。拿一把锁然后在没有解锁的情况下睡觉是很粗鲁的,但肯定是可能的。或者也许其中一个运行代码的线程没有源代码来取出锁。例如,假设终结器线程在最终确定对象时取出了锁,然后终结器线程完成了当前的一批工作。同样,在最终确定期间锁定对象然后不解锁它是粗鲁和愚蠢的,但它肯定是可能的。
有一百万种可能性;你没有给我们足够的信息来做任何事情,而不是随意猜测。我的建议是:建立一个能够清楚地证明问题的小型复制品。在这样做的过程中,你要么弄清楚问题本身是什么,要么你会得到一些我们可以讨论的具体内容,而不是简单地在事实之前做出猜测。
答案 1 :(得分:3)
调试此方法的一个好方法是通过Visual Studio 2010中的Concurrency Profiler运行程序。(但这仅适用于高端SKU。)它包含许多用于突出显示和调查死锁的工具,并且倾向于在许多情况下比调试器更好地工作。