2011-04-11 57 views
0

我的應用程序在對lock (obj)的調用中無限期地被阻止,但線程窗口中沒有任何其他線程有任何代碼可以瀏覽。有沒有必要有另一個線程參與?爲什麼它沒有出現,並且它沒有出現的原因是什麼?如何在Visual Studio中只顯示一個線程時調試死鎖?

更新:我想我找出是什麼原因造成的。我有這種黑客塊,我會Wait()在兩個鎖裏面的ManualResetEvent。問題是我需要等待,以便其他線程可以使用它們之前釋放這些鎖,所以我在做這樣的事情:

lock (one) { 
    lock (two) { 
     ... 
     Monitor.Exit(two); 
     Monitor.Exit(one); 
     syncEvent.Wait(); 
     Monitor.Enter(one); 
     Monitor.Enter(two); 
    } 
} 

我並沒有指望的是,Monitor.Exit()實際上只是減少一個內部遞歸計數器,並且有可能從已經同步的塊中調用該方法;因此該鎖實際上並不是發佈的

我想這是一個壞主意開始。自那時起,我就把電話轉到Wait()以外的鎖定區域,現在看起來工作正常。

感謝您的洞察力。

儘管現在我想到了,如果方法是從其中一個鎖上同步的代碼調用的,當發生對Wait的調用時,它仍不會被釋放。因此,我想必須小心,不要從同步塊中調用它。

+1

可能那些其他線程已經走了 - 還是還沒有創建? – user492238 2011-04-11 17:20:46

回答

6

有在線程窗口中沒有其他線程有任何代碼

瀏覽我向你保證,這些其他線程運行的代碼。無論您的機器上是否有源代碼,都與這些線程無關。

是不是有必要有另一個線程參與?

是的。

爲什麼不顯示出來,可能是什麼原因沒有顯示出來?

也許鎖定的線程已經進入睡眠狀態。鎖定然後睡覺而不解鎖它是不禮貌的,但當然可能。或者也許是運行代碼的那些線程之一,您沒有源代碼來取出鎖。例如,假設終結器線程在完成對象時取出了鎖,然後終結器線程完成了其當前的一批工作。同樣,在最終確定期間鎖定對象並且不解鎖它是粗魯和愚蠢的,但它當然是可能的。

有一百萬種可能性;你沒有給我們足夠的信息來做任何事情,而不是隨機猜測。我的建議是:建立一個清晰顯示問題的小型回放。在這樣做的時候,你要麼找出自己的問題是什麼,要麼就會有一些我們可以討論的具體事情,而不是在事實發生前進行猜測。

3

調試此方法的一個好方法是通過Visual Studio 2010中的併發事件探查器運行您的程序(但是,這隻適用於高端SKU)。它包含許多突出顯示和調查死鎖的工具,以及在許多情況下比調試器更好地工作。