逐步解說:使用 [執行緒] 視窗對多執行緒應用程式偵錯 (C#、Visual Basic、C++)
數個 Visual Studio 使用者介面元素可協助您對多執行緒應用程式進行偵錯。 本文介紹程式碼編輯器視窗、[偵錯位置] 工具列和 [執行緒] 視窗中的多執行緒偵錯功能。 如需偵錯多執行緒應用程式的其他工具相關資訊,請參閱開始對多執行緒應用程式進行偵錯。
完成本教學課程只需要幾分鐘的時間,並熟悉偵錯多執行緒應用程式的基本概念。
建立多執行緒應用程式專案
建立下列多執行緒應用程式專案,以在本教學課程中使用:
開啟 Visual Studio 並建立新專案。
如果開始視窗未開啟,請選擇 [檔案]>[開始視窗]。
在開始視窗中,選擇 [新增專案]。
在開始視窗中,選擇 [建立新專案]。
在 [建立新專案] 視窗的搜尋方塊中輸入或鍵入 console。 接下來,從語言清單中選擇 [C#] 或 [C++],然後從 [平台] 清單中選擇 [Windows]。
套用語言和平台篩選後,為 .NET Core、NET 5+或 C++ 選擇 「[主控台應用程式],然後選擇 [下一步]。
注意
如果看不到正確的範本,請移至 [工具]>[取得工具和功能...],這將開啟 Visual Studio 安裝程式。 選擇 [NET 桌面開發] 或 [使用 C++ 的桌面開發] 工作負載,然後選擇 [修改] 按鈕。
在 [設定新專案] 視窗中,在 [專案名稱] 方塊中輸入名稱或使用預設名稱。 然後,選擇 [下一步] 或 [建立],無論哪個選項可用。
對於 .NET Core 或 .NET 5+,請選擇建議的目標框架或 .NET 8,然後選擇 [建立]。
新的主控台專案隨即出現。 建立專案之後,便會出現來源檔案。 根據您所選擇的語言,來源檔案的名稱可能是 Program.cs 或 MyThreadWalkthroughApp.cpp。
從開始對多執行緒應用程式進行偵錯,將來源檔案中的程式碼取代為 C# 或 C++ 範例程式碼。
選取 [檔案]>[儲存全部]。
開始偵錯
在原始程式碼中尋找下列幾行:
按一下左側裝訂邊,或選取該行,然後按 F9,在
Console.WriteLine();
上設定中斷點。中斷點會在程式碼旁的左側裝訂邊中顯示為紅色圓圈。
選取 [偵錯]>[開始偵錯],或按 [F5]。
應用程式會以偵錯模式啟動,並在中斷點暫停。
處於中斷模式時,選取偵錯>視窗>執行緒來開啟執行緒視窗。 您必須在偵錯工作階段中,才能開啟或查看 [執行緒] 和其他偵錯視窗。
檢查執行緒標記
在原始程式碼中,找出
Console.WriteLine();
行。- 在 [執行緒] 視窗中按一下滑鼠右鍵,然後從功能表中選取 [在來源中顯示執行緒]。
原始程式碼旁的裝訂邊現在會顯示 執行緒標記 圖示 。 執行緒標記表示執行緒會停在這個位置上。 如果位置有多個已停止的執行緒,圖示 隨即出現。
將指標移到執行緒標記上。 此時會出現一個 DataTip,顯示已停止執行緒或執行緒的名稱和執行緒識別碼。 執行緒名稱可能是
<No Name>
。提示
若要協助識別無名稱執行緒,您可以在 [執行緒] 視窗中重新命名它們。 以滑鼠右鍵按一下執行緒,然後選取 [重新命名]。
以滑鼠右鍵按一下原始程式碼中的執行緒標記,以查看捷徑功能表上的可用選項。
將執行緒加上旗標和取消旗標
您可以標記執行緒,以追蹤您想要特別注意的執行緒。
從原始程式碼編輯器或 [執行緒] 視窗標記和解除標記執行緒。 選擇是否只顯示 [偵錯位置] 或 [執行緒] 視窗工具列中已標幟的執行緒或顯示所有執行緒。 從任何位置進行的選取項目會影響所有位置。
將原始程式碼中的執行緒加上旗標和取消旗標
選取檢視>工具列>偵錯位置來開啟偵錯位置工具列。 您也可以在工具列區域中按一下滑鼠右鍵,然後選取 [偵錯位置]。
[偵錯位置] 工具列有三個欄位:[處理序]、[執行緒] 和 [堆疊框架]。 下拉式清單的 [執行緒] 清單,並記下有多少個執行緒。 在 [執行緒] 清單中,目前執行的執行緒會以 > 符號標示。
在原始程式碼視窗中,將滑鼠暫留在裝訂邊中的執行緒標記圖示上,然後在 DataTip 中選取旗標圖示 (或其中一個空白旗標圖示)。 旗標圖示會變成紅色。
您也可以以滑鼠右鍵按一下執行緒標記圖示,指向 [旗標],然後從捷徑功能表中選取要加上旗標的執行緒。
在偵錯位置工具列上,選取執行緒欄位右邊的僅顯示已標幟的執行緒圖示。 除非已標幟一或多個執行緒,否則圖示會呈現灰色。
工具列的 [執行緒] 下拉式清單中現在只會顯示已標幟的執行緒。 若要再次顯示所有執行緒,請再次選取 [只顯示已標幟的執行緒] 圖示。
提示
某些執行緒加上旗標之後,您可以將游標放在程式碼編輯器中,以滑鼠右鍵按一下,然後選取 [將已標幟的執行緒執行至游標]。 請務必選擇所有已標幟執行緒都會到達的程式碼。 [將已標幟的執行緒執行至游標] 會在選取的程式碼上暫停執行緒,可凍結及解除凍結執行緒,更輕鬆地控制執行順序。
若要切換目前執行執行緒的已標幟或未標幟狀態,請選取僅顯示已標幟的執行緒按鈕左側的切換目前執行緒標幟狀態工具列按鈕的單一旗標。 當只有已標幟的執行緒顯示時,標幟目前的執行緒就很有用。
若要將執行緒取消旗標,請將滑鼠暫留在原始程式碼中的執行緒標記上,然後選取紅色旗標圖示以清除它,或以滑鼠右鍵按一下執行緒標記,然後選取 [取消旗標]。
在 [執行緒] 視窗中將執行緒加上旗標或取消旗標
在 [執行緒] 視窗中,已標幟的執行緒旁邊會有紅色旗標圖示,而未標幟的執行緒則顯示空白的外框圖示。
選取旗標圖示,根據執行緒狀態,將執行緒狀態變更為已加上旗標或解除旗標。
您也可以以滑鼠右鍵按一下一行,然後從捷徑功能表選取 [加上旗標]、[取消旗標] 或 [將所有執行緒取消旗標]。
[執行緒] 視窗工具列也有 [僅顯示已標幟的執行緒] 按鈕,這是兩個旗標圖示的右側其中一個。 其運作方式與 [偵錯位置] 工具列上的按鈕相同,而任一按鈕都會控制這兩個位置中的顯示。
其他執行緒視窗功能
在 [執行緒] 視窗中,選取任何資料行的標頭,依該資料行排序執行緒。 再次選取以反轉排序排序。 如果所有執行緒都顯示,選取旗標圖示資料行會依已標幟或未標幟的狀態來排序執行緒。
[執行緒] 視窗的第二個資料行 (無標頭) 是 [目前執行緒] 資料行。 此資料行中的黃色箭號會標示目前的執行點。
[位置] 資料行會顯示每個執行緒出現在原始程式碼中的位置。 選取 [位置] 項目旁的展開箭號,或將滑鼠暫留在項目上,以顯示該執行緒的部分呼叫堆疊。
提示
如需執行緒呼叫堆疊的圖形化檢視,請使用 [平行堆疊] 視窗。 若要開啟視窗,請在偵錯時選取 [偵錯]>[視窗]>[平行堆疊]。
除了 [加入旗標]、[取消旗標] 和 [將所有執行緒取消旗標] 之外,[執行緒] 視窗項目的右鍵捷徑功能表還有:
- [在來源中顯示執行緒] 按鈕。
- 十六進位顯示,會將執行緒視窗中的執行緒識別碼從十進位變更為十六進位格式。
- 切換至執行緒,這會立即將執行切換至該執行緒。
- 重新命名,可讓您變更執行緒名稱。
- 凍結和解除凍結 命令。
凍結及解除凍結執行緒執行
您可以凍結及解除凍結或暫停和繼續執行緒,以控制執行緒執行工作的順序。 凍結和解除凍結執行緒可協助您解決並行問題,例如死結和競爭條件。
提示
若要遵循單一執行緒而不凍結其他執行緒,這也是常見的偵錯案例,請參閱開始對多執行緒應用程式進行偵錯。
凍結和解除凍結執行緒:
在 [執行緒] 視窗中,以滑鼠右鍵按一下任何執行緒,然後選取 [凍結]。 目前執行緒資料行中的暫停圖示表示該執行緒已凍結。
在執行緒視窗工具列中選取資料行,然後選取已擱置的計數以顯示已擱置的計數資料行。 凍結執行緒的已擱置計數值為 1。
以滑鼠右鍵按一下凍結的執行緒,然後選取 [解除凍結]。
[暫停] 圖示會消失,而 [已擱置的計數] 值會變更為 0。
切換到另一個執行緒
當您嘗試切換到另一個執行緒時,您可能會看到 [應用程式處於中斷模式] 視窗。 此視窗會告訴您執行緒沒有任何程式碼可供目前偵錯工具顯示。 例如,您可能正在偵錯受控程式碼,但執行緒是機器碼。 該視窗提供解決問題的建議。
切換到另一個執行緒:
在 [執行緒] 視窗中,記下目前的執行緒識別碼,也就是 [目前執行緒] 資料行中有黃色箭號的執行緒。 您會想要切換回此執行緒,以繼續您的應用程式。
以滑鼠右鍵按一下不同的執行緒,然後從捷徑功能表中選取 [切換至執行緒]。
觀察 [執行緒] 視窗中的黃色箭號位置已變更。 原始目前的執行緒標記也會保留為外框。
查看原始程式碼編輯器中執行緒標記上的工具提示,以及偵錯位置工具列上執行緒下拉式清單中的清單。 觀察目前執行緒也已在那裡變更。
在 [偵錯位置] 工具列上,從 [執行緒] 清單中選取不同的執行緒。 請注意,目前執行緒也會變更其他兩個位置。
在原始程式碼編輯器中,以滑鼠右鍵按一下執行緒標記,指向 [切換至執行緒],然後從清單中選取另一個執行緒。 觀察目前執行緒在這三個位置中的變更。
使用原始程式碼中的執行緒標記時,您只能切換至在該位置停止的執行緒。 使用 [執行緒] 視窗和 [偵錯位置] 工具列時,您可以切換至任何執行緒。
您現在已了解對多執行緒應用程式進行偵錯的基本概念。 您可以使用執行緒視窗、偵錯位置工具列中的執行緒清單,或原始程式碼編輯器中的執行緒標記來觀察、加上旗標和取消旗標,以及凍結和解除凍結執行緒。