我有一个奇怪的问题,一个死锁问题,如果我使用Visual Studio暂停程序并检查线程,我只能看到两个线程等待锁定。没有线程出现在锁定范围内! Visual Studio只是在撒谎,或者如何在不释放锁的情况下退出锁定语句?
由于
答案 0 :(得分:9)
在下列情况下可能会发生这种情况。假设你有
Enter();
try
{
Foo();
}
finally
{
Exit();
}
并在Enter之后但在尝试之前抛出线程中止异常。现在已经输入了监视器,但是终于永远不会运行,因为在尝试之前抛出了异常。
我们已经修复了C#4中的这个缺陷。在C#4中,lock语句现在生成为
bool mustExit = false;
try
{
Enter(ref mustExit);
Foo();
}
finally
{
if (mustExit) Exit();
}
当然,事情仍然可能是错误的;中止线程并不能保证线程永远中止,最终阻塞运行,等等。您仍然可以在未处理的异常事件处理程序中结束锁定。但这至少要好一点。
答案 1 :(得分:2)
如果您在不致电Monitor.Enter(something)
的情况下手动拨打Monitor.Exit
,就会发生这种情况。
答案 2 :(得分:1)
您的代码中是否有对Monitor.Enter
/ Monitor.TryEnter
的明确调用?你能看到那些等待线程的堆栈跟踪吗?如果是这样,看看他们在等待的地方 - 这应该是显而易见的。
答案 3 :(得分:0)
您是否有机会从线程池线程的锁定语句中调用yield return?
如果是这种情况,您可能需要查看Yielding surprises
这篇博文描述了一个错误(我被锁定了),当我以错误的方式合并这三件事时,我遇到了这个错误。幸运的是,我只是通过对代码进行一些小改动来解决问题。