1. 程式人生 > >12個Visual Studio除錯效率技巧

12個Visual Studio除錯效率技巧

![](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707214059024-23476906.jpg) 在這篇文章中,我們假定讀者瞭解`VS`基本的除錯知識,如: * **F5** 開始使用偵錯程式執行程式 * **F9** 在當前行設定斷點 * **F10** 執行到下一個斷點處 * **F5** 從被除錯的已停止程式恢復執行 * **F11** 步進到函式內(如果當前程式指標指向一個函式) * **F10** 步過函式(如果當前程式指標指向一個函式) * **Shift+F11** 步出執行的函式 * 暫停執行 * 附加到程序 * 滑鼠懸停時快速檢視原始碼中的元素 * 除錯視窗:區域性變數、監視、即時視窗、模組、呼叫堆疊、異常設定 許多開發人員使用這個功能強大的工具包來處理除錯會話。然而,`Visual Studio`除錯工具提供了更多的功能。下面是一系列Visual Studio除錯效率技巧。注意,這些提示和快捷方式已經在的Visual studio 2019 16.6 EN-US版本中進行了驗證,驗證時`Visual studio`沒有安裝擴充套件。 ## 1、執行到游標位置 使用快捷鍵**`Ctrl+F10`**,您可以讓偵錯程式執行到游標所在行位置。 ![`Ctrl+F10`執行到游標位置](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707155332011-1275092655.gif) ## 2、通過點選滑鼠,執行到當前位置 在除錯執行的程式時,通過滑鼠懸停在當前行的程式碼上時,出現綠色的符號,可以點選此符號,直接讓斷點執行到此處。 ![通過點選滑鼠,執行到當前位置](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707160349703-1780938163.gif) ## 3、在此處作為下一條要執行的語句 在除錯執行的程式時,通過滑鼠懸停在當前行的程式碼上時,通過按住`Ctrl`鍵轉換為將此處作為下一條要執行的語句。它與通過綠色箭頭符號執行到這裡不同,此功能將會跳過中間的語句,直接將斷點跳轉到此處。因此,在下面的動圖中,我們可以在監視視窗中引用obj仍然為null,中間的`MyClass`建構函式並沒有被執行。 ![在此處作為下一條要執行的語句](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707161252195-1330476934.gif) ## 4、資料斷點:當值發生變化時,觸發中斷(值更改時中斷) 當你設定一個非靜態的設定器為斷點時,當所有物件的屬性的值發生更改時觸發斷點。通過區域性視窗(監視器視窗)右鍵點選:`值更改時中斷`選單,單個物件也可以獲得相同的行為。 下面的動畫說明了這個功能,只有當`obj2.Prop`發生變化時,命中斷點,而`obj1.Prop`發生變化時沒有命中斷點。 *注意:資料斷點繫結到活動物件時,旨在除錯期間起作用。因此,一旦除錯過程停止,設定的斷點就會丟失,在以後的除錯過程中不能重用它。* ![資料斷點:值更改時中斷](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707162236961-572885771.gif) ## 5、條件斷點 可以將條件附加到斷點中,以便盡在特定場景中觸發中斷。在下面的動圖中,我們在迴圈中定義條件`i>6`的斷點。然後點選`繼續`,可以看到一旦斷點停止,`i`的值實際上變成了`7`。 ![](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707164038689-2066710870.gif) ## 6、跟蹤斷點 在遇到斷點時,停止程式執行時最常見的操作。但是,你可以選擇在輸出視窗中不終止(或帶終止)列印一些跟蹤資訊。下面的動圖說明了這種可能性。我們在輸出視窗中跟蹤i從0到9的值。注意:跟蹤斷點在編輯器的斷點顯示位置顯示為菱形形狀。 *注意,條件和跟蹤操作都可以在斷點上指定。* ![跟蹤斷點](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707164934670-176032503.gif) ## 7、跟蹤超出作用域的物件 在監視視窗中,通過當前執行範文內引用的名稱來跟蹤物件。但是,當這樣的跟蹤引用超出作用域時,即使在引用物件仍處於活動狀態時,它在監視視窗的上下文也不安的毫無意義並且被禁用。 在許多情況下,我們想繼續跟蹤作用域外物件的狀態。為此,請在監視視窗中右鍵單擊此類引用,單擊選單`[Make Object ID] 建立物件ID(M)`,並要在監視器中新增$1(或者$2,$3,...,取決於你已經建立了多個物件ID)。 下面的動圖演示瞭如何跟蹤作用域外物件的屬性獲取器的狀態,該屬性獲取器以字串的形式返回實際的日期時間。它很好地顯示了當引用`obj`在`Fct()`上下文中超出作用域時,要觀看的`obj`項將被禁用,而`$1`仍然會獲得更新。 ![跟蹤超出作用域的物件](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707170738140-1279961544.gif) ## 8、檢視函式返回的值 函式返回的值有時在原始碼中被忽略,或者有時這個值在除錯時無法被顯示的訪問。 這樣的返回值可以顯示在`除錯->視窗->自動視窗`中。偽變數`$ReturnValue`也可以在即時視窗和監視視窗中使用,以方便檢視最後一個函式呼叫的返回值。 *注意,選單`除錯->視窗->自動視窗`僅在`Visual Studio`偵錯程式附加到程序並且程式被偵錯程式暫停時可用。* ![檢視函式返回的值](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707171525405-2143885851.gif) ## 9、重新附加到程序 從`Visual Studio 2017`開始,重新附加到程序`Shift+Alt+P`工具被提出,並且非常方便。將偵錯程式附加到某個程序後,`Visual Studio`會記住它,並建議將偵錯程式重新附加到同一程序。斜體也一樣,因為這裡有一個關於程序標識的啟發式方法: * 如果已附加的程序仍然執行著,重新附加到程序,重新附加到它。 * 否則,`Visual Studio`將嘗試查詢和前一個程序名具有相同名稱的單程序,並將偵錯程式重新附加到該程序。 * 如果找到幾個使用此名稱的程序,則開啟“附加到程序”對話方塊,只顯示名稱相同的程序 * 如果找不到具有此名稱的程序,則顯示“附加到程序”對話方塊 ![重新附加到程序](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707172625434-457205959.gif) 重新附加到程序也適用於涉及多個程序的除錯會話。在這種情況下,`Visual Studio`會嘗試使用上述相同的啟發式方法來查詢它附加到的所有程序。 ## 10、在即時視窗和在觀察視窗的`No-Side-Effect`評估 有時,在即時視窗或監視視窗中評估表示式時,某些狀態會更改。這種行為通常時不希望發生的。你不想僅僅因為需要評估表示式的值而破壞除錯程式的狀態。這種情況被稱為`Heisenbug`,該術語時物理學家`Werner Heisenberg`的雙關語,它首先斷言了量子力學的觀察者效應,該現象指出,觀察系統的行為不可避免的會改變器狀態。 為了避免更改任何狀態,你可以在表示式後面加上`nse`(No-Side-Effect)。下面的動圖說明了這種可能性(在監視視窗中監視`State`的值是否有變化)。 ![在即時視窗和在觀察視窗的`No-Side-Effect`評估](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707205927346-1804320744.gif) 下面這種動圖是`nse`在監視視窗的使用。由於`SideEffectFct()`所觀察的項中有`Refresh`評估按鈕,所以此示例比前一個示例更簡單。 ![](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707210248534-2125472777.gif) ## 11、在原始碼中顯示執行緒 除錯多執行緒應用程式是有名的複雜。希望`在原始碼中顯示執行緒`按鈕能提供很大的幫助。它在編輯器的左側邊欄引入標記圖示,以跟蹤其他執行緒被暫停的位置。這個標記可以用來顯示執行緒`ID`,並最終切換到另一個執行緒。注意:如果至少兩個執行緒在同一位置暫停,則會顯示不同的標記符號。 ![在原始碼中顯示執行緒](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707210855228-1417000542.gif) 更多除錯多執行緒應用程式的技巧可以在這個微軟文件中找到:[Get started debugging multithreaded applications (C#, Visual Basic, C++)](https://docs.microsoft.com/en-us/visualstudio/debugger/get-started-debugging-multithreaded-apps?view=vs-2019) [https://docs.microsoft.com/en-us/visualstudio/debugger/get-started-debugging-multithreaded-apps?view=vs-2019](https://docs.microsoft.com/en-us/visualstudio/debugger/get-started-debugging-multithreaded-apps?view=vs-2019) 下面是這個演示的原始碼,如果你想演示它,可以進行參考: ``` using System; using System.Threading; class Program { static void Main() { for (int i=0; i< 5; i++) { // Avoid capturing a loop variable in the lambda below int j = i; // So 2 thread are blocked on '0' case if (j == 1) { j = 0; } ThreadPool.QueueUserWorkItem(delegate { Method(j); }); } Thread.Sleep(60000); } static void Method(int id) { switch(id) { case 0: Thread.Sleep(60000); break; case 1: Thread.Sleep(60000); break; case 2: Thread.Sleep(60000); break; case 3: Thread.Sleep(60000); break; case 4: Thread.Sleep(60000); break; } } } ``` ## 12、從反編譯的IL程式碼中除錯原始碼 我們經常依賴一些黑盒元件:我們沒有原始碼的元件。 但是,在除錯複雜行為時,觀察甚至除錯引用的黑盒元件引用的邏輯。這就是為什麼從16.5版本開始,`Visual Studio 2019`可以從編譯好的程式中生成一些原始碼。這樣的原始碼是可以除錯的。這個特性是基於開源軟體(OSS)工程:ILSpy([https://github.com/icsharpcode/ILSpy](https://github.com/icsharpcode/ILSpy))。 反編譯選單可以在模組視窗的元件右鍵選單(如下面的動圖所示)和`Source Not Found`或`No Symbols Loaded`對話方塊中給出。 將`IL`程式碼反編譯為原始碼不可能是完美的,因為一些原始碼資訊在編譯時丟失了。因此,這個特性有一些限制,在這個官方文件的最後會解釋:[Generate source code from .NET assemblies while debugging](https://docs.microsoft.com/en-us/visualstudio/debugger/decompilation?view=vs-2019) [https://docs.microsoft.com/en-us/visualstudio/debugger/decompilation?view=vs-2019](https://docs.microsoft.com/en-us/visualstudio/debugger/decompilation?view=vs-2019) ![從反編譯的IL程式碼中除錯原始碼](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707212418830-215489573.gif) ## 結尾 Visual Studio非常出色,在除錯方面尤其出色。 在這裡,我試圖選擇一些既隱藏又經常有用的技巧,希望它們能幫助您提高生產率。 如果你感覺有用,請關注一下我的公眾號 ![](https://img2020.cnblogs.com/blog/1746998/202007/1746998-20200707214421098-1653055661.png)