当只有一个线程出现在Visual Studio中时,如何调试死锁?

dev*_*os1 0 .net c# concurrency deadlock visual-studio

我的应用程序在调用时无限期地阻塞lock ( obj ),但线程窗口中没有其他线程可以根据需要进行任何代码浏览.是不是有必要涉及另一个线程?它为什么不出现,它可能是什么原因没有出现?

更新:我想我弄明白是什么导致了它.我有这种hackish阻止,我会Wait()ManualResetEvent内部两个锁.问题是我需要在等待之前释放这些锁,以便其他线程可以使用它们,所以我做了类似这样的事情:

lock ( one ) {
    lock ( two ) {
        ...
        Monitor.Exit( two );
        Monitor.Exit( one );
        syncEvent.Wait();
        Monitor.Enter( one );
        Monitor.Enter( two );
    }
}
Run Code Online (Sandbox Code Playgroud)

我不指望的是,Monitor.Exit()实际上只减少内部递归计数器,并且可能从已经同步的块调用该方法; 因此锁实际上并没有被释放.

我想从一开始就是一个坏主意.我刚刚将呼叫转移到Wait()锁定区块之外,现在似乎工作正常.

感谢您的见解.

虽然,现在我考虑一下,如果从其中一个锁上的代码同步调用该方法,则在调用Wait发生时仍然不会释放该方法.因此,我想要小心,永远不要从同步块中调用它.

Eri*_*ert 6

线程窗口中没有其他线程可以完全浏览任何代码

我向你保证,其他线程正在运行代码.您是否在计算机上拥有源代码与这些线程无关.

是不是有必要涉及另一个线程?

是.

它为什么不出现,它可能是什么原因没有出现?

也许拿出锁的线程已经进入睡眠状态.拿一把锁然后在没有解锁的情况下睡觉是很粗鲁的,但肯定是可能的.或者也许其中一个运行代码的线程没有源代码来取出锁.例如,假设终结器线程在最终确定对象时取出锁定,然后终结器线程完成其当前的一批工作.同样,在最终确定期间锁定对象然后不解锁它是粗鲁和愚蠢的,但它肯定是可能的.

有一百万种可能性; 你没有给我们足够的信息来做任何事情,而不是随机猜测.我的建议是:建立一个能够清楚地证明问题的小型复制品.在这样做的过程中,你要么弄清楚问题本身是什么,要么你会有一些我们可以讨论的具体内容,而不是简单地在事实之前做出猜测.