2010-03-10 37 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

本博客文章描述了一個錯誤(我被鎖定)我遇到我時,結合這三樣東西走錯了路。幸運的是,我只是想通過對代碼的小改動來解決問題。

相關問題