在 Visual Studio 2019 (16.5) 中查看託管執行緒正在等待的鎖被哪個執行緒佔用
- 2020 年 4 月 3 日
- 筆記
Visual Studio 2019 (16.5) 版本更新中帶來了一項很小很難注意到卻非常實用的功能,查看哪一個託管執行緒正在持有 .NET 對象鎖。
如果你不了解這個功能如何使用,那麼可以閱讀本文。
更新日誌
Visual Studio 的官方更新日誌中對此功能的描述:
View which managed thread is holding a .NET object lock
即「查看託管執行緒正在持有 .NET 對象鎖」。
功能入口
這個功能沒有新的入口,你可以在「調用堆棧」 (Call Stack) 窗口,「並行堆棧」 (Parallel Stacks) 窗口,以及「執行緒」窗口的位置列中查看哪個託管執行緒正在持有 .NET 對象鎖。
示例
現在我們就實際看一下這個功能的用法和效果。於是我寫了一點下面的程式碼。
static void Main(string[] args) { var locker = new object(); Thread thread = new Thread(() => { Console.WriteLine("後台執行緒嘗試獲得鎖"); lock (locker) { Console.WriteLine("後台執行緒成功獲得鎖"); } }) { Name = "walterlv thread", }; Console.WriteLine("主執行緒嘗試獲得鎖"); Monitor.Enter(locker); Console.WriteLine("主執行緒成功獲得鎖"); thread.Start(); }
在這段程式碼中,主執行緒獲得鎖之後直接退出,而新執行緒「walterlv thread」則嘗試獲得鎖。
現在在 Visual Studio 2019 中運行這段程式碼,可以看到另一個執行緒是不可能獲得鎖的,於是不會輸出最後那一句,其他都會輸出。

隨後我們在 Visual Studio 中點擊「全部中斷」,也就是那個「暫停」圖標的按鈕。

打開調用堆棧窗口(在「調試 -> 窗口 -> 調用堆棧」),可以看到堆棧最頂端顯示了正在等待鎖,並且指出了執行緒對象。

然後在執行緒窗口(在「調試 -> 窗口 -> 執行緒「)的位置列,滑鼠移上去可以看到與堆棧中相同的資訊。

當然,我們的主執行緒實際上早已直接退出了,所以正在等待的鎖將永遠不會釋放(除非進程退出)。
同樣的資訊,在並行堆棧(在「調試 -> 窗口 -> 並行堆棧」)中也能看到。

參考資料
- Visual Studio 2019 version 16.5 Release Notes – Microsoft Docs
- Visual Studio 2019 version 16.5 is now available – Visual Studio Blog