2010-03-10 40 views
4

我有一个奇怪的问题,死锁问题,如果我使用Visual Studio暂停程序并检查线程,我只能看到两个线程正在等待锁定。没有线程出现在锁定范围内! Visual Studio是说谎还是锁定语句如何不释放锁定?锁定语句如何在不释放锁定的情况下退出?

感谢

+0

视觉工作室可能会说谎:)但你确定你总是释放锁吗?有不止一个锁吗? – 2010-03-10 16:29:02

+0

我正在使用标准的锁语句,所以锁应该总是被释放.....使用try,最后锁被扩展到。 – CodingThunder 2010-03-10 16:33:48

+0

你锁定了什么对象? – SLaks 2010-03-10 16:40:12

回答

1

你有没有在你的代码中显式调用Monitor.Enter/Monitor.TryEnter?你能看到那些等待线程的栈跟踪吗?如果是这样,看看他们在等待的地方 - 这应该是显而易见的。

+0

我只是使用标准的锁定语句。没有监视器方法。我可以看到两个线程正在等待同一个锁对象。他们的调用堆栈看起来很好,但我看不到锁内的任何线程。 hrmmm ...不知道发生了什么事。 – CodingThunder 2010-03-10 16:32:36

+0

啊,所以他们在等待“正常”锁定语句,但你不知道他们为什么在等待?我懂了。嗯...这是多么的可重复? – 2010-03-10 17:08:12

+0

是的,我看不出为什么2个线程正在等待。没有线程似乎在锁里面......只要Visual Studio的线程窗口允许我。我已经复制了两次,结果相同。但是,这不应该是正确的?谢谢 – CodingThunder 2010-03-10 17:20:00

9

这可能发生在下列情况下。假设你有

Enter(); 
try 
{ 
    Foo(); 
} 
finally 
{ 
    Exit(); 
} 

和一个线程中止异常在Enter之后但在try之前抛出。现在显示器已经进入,但终于永远不会运行,因为在尝试之前抛出异常。

我们已修复这个漏洞在C#4。在C#4锁定语句现在作为

产生
bool mustExit = false; 
try 
{ 
    Enter(ref mustExit); 
    Foo(); 
} 
finally 
{ 
    if (mustExit) Exit(); 
} 

东西还是可以去可怕的错误,当然,放弃一个线程并不能保证线程终止,最终阻止永远运行,等等。您仍然可以在未处理的异常事件处理程序中结束锁定。但这至少要好一点。

+3

我刚刚发布了相同的内容,因为我记得在“The C#Programming Language,3rd Ed。”中阅读了一个关于此效果的注释,但是您打败了我它。不过,当我查阅参考资料时,我记得的笔记(第8.12节第386页)实际上是由你写的,所以我猜你*真的*打败了我...... :-) – 2010-03-10 21:29:51

0

你是否有机会从线程池线程的锁语句中调用yield return?

如果是这样的话,你可能想看看Yielding surprises

本博客文章描述了一个错误(我被锁定)我遇到我时,结合这三样东西走错了路。幸运的是,我只是想通过对代码的小改动来解决问题。

相关问题