在 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