Share via


在 Visual Studio 中使用偵錯工具管理例外狀況

例外狀況是程式執行時發生之錯誤狀態的指示。 您可以告訴偵錯工具要中斷的例外狀況或例外狀況集,以及您希望偵錯工具中斷 (也就是在偵錯工具中暫停) 的點。 偵錯工具中斷時,會顯示擲回例外狀況的位置。 您也可以新增或刪除例外狀況。 在 Visual Studio 中開啟方案時,請使用 [偵錯] > [Windows] > [例外狀況設定] 來開啟 [例外狀況設定] 視窗。

提供回應最重要例外狀況的處理常式。 如果您需要知道如何新增例外狀況的處理常式,請參閱撰寫更好的 C# 程式碼來修正錯誤。 此外,了解如何設定偵錯工具,以一律中斷執行某些例外狀況。

發生例外狀況時,偵錯工具都會將例外狀況訊息寫入至 [輸出] 視窗。 在下列情況下,其可能會中斷執行:

  • 擲回未處理的例外狀況。
  • 偵錯工具會設定為在叫用任何處理程式之前中斷執行。
  • 您曾設定 Just My Code,且偵錯工具設定為在非由使用者程式碼所處理的任何例外狀況時中斷。

注意

ASP.NET 具有最上層例外狀況處理常式,這會在瀏覽器中顯示錯誤頁面。 其不會中斷執行,除非 [Just My Code] 已開啟。 如需範例,請參閱下列告知偵錯工具在擲回例外狀況時中斷

注意

在 Visual Basic 應用程式中,即使使用 On Error 樣式的錯誤處理常式,偵錯工具還是會將所有錯誤都當成例外狀況管理。

告知偵錯工具在擲回例外狀況時中斷

偵錯工具可以在擲回例外狀況的位置中斷執行,因此您可以在叫用處理常式之前檢查例外狀況。

在 [例外狀況設定] 視窗中 ([偵錯] > [Windows] > [例外狀況設定]),展開例外狀況類別的節點,例如 Common Language Runtime 例外狀況。 然後選取該類別內特定例外狀況的核取方塊,例如 System.AccessViolationException。 您也可以選取例外狀況的整個類別。

Screenshot of Exception Settings check box.

Screenshot of Exception Settings check box.

提示

您可以使用 [例外狀況設定] 工具列中的 [搜尋] 視窗,尋找特定的例外狀況,或使用搜尋來篩選特定命名空間 (例如 [System.IO])。

如果您在 [例外狀況設定] 視窗中選取例外狀況,則無論是否處理例外狀況,偵錯工具執行都會中斷擲回例外狀況的位置。 現在,該例外狀況稱為第一個可能發生的例外狀況。 例如,以下是幾個情節:

  • 在下列 C# 主控台應用程式中,Main 方法會在 try/catch 區塊內部擲回 try/catch

    static void Main(string[] args)
    {
        try
        {
            throw new AccessViolationException();
            Console.WriteLine("here");
        }
        catch (Exception e)
        {
            Console.WriteLine("caught exception");
        }
        Console.WriteLine("goodbye");
    }
    

    當您在偵錯工具中執行此程式碼時,如果您在 [例外狀況設定] 中核取了 [AccessViolationException],則執行會在 throw 行中斷。 然後,您可以繼續執行。 主控台應該會顯示這兩行:

    caught exception
    goodbye
    

    但其不會顯示 here 行。

  • C# 主控台應用程式會參考包含類別具有兩種方法的類別庫。 一個方法會擲回例外狀況並加以處理,而第二個方法會擲回相同的例外狀況,但不會加以處理。

    public class Class1
    {
        public void ThrowHandledException()
        {
            try
            {
                throw new AccessViolationException();
            }
            catch (AccessViolationException ave)
            {
                Console.WriteLine("caught exception" + ave.Message);
            }
        }
    
        public void ThrowUnhandledException()
        {
            throw new AccessViolationException();
        }
    }
    

    以下是主控台應用程式的 Main () 方法:

    static void Main(string[] args)
    {
        Class1 class1 = new Class1();
        class1.ThrowHandledException();
        class1.ThrowUnhandledException();
    }
    

    如果您在 [例外狀況設定] 中核取了 [AccessViolationException],則當您在偵錯工具中執行此程式碼時,執行會在 ThrowHandledException()ThrowUnhandledException() 兩者中的 throw 行中斷。

若要將例外狀況設定還原為預設值,請選擇 [將清單還原為預設設定] 按鈕:

Screenshot of Restore Defaults in Exception Settings.

Screenshot of Restore Defaults in Exception Settings.

告知偵錯工具繼續處理使用者未處理的例外狀況

如果您正在偵錯具有 Just My Code 的 .NET 或 JavaScript 程式碼,則可以告知偵錯工具不要中斷使用者程式碼中未處理,但在其他地方處理的例外狀況。

  1. 在 [例外狀況設定] 視窗中,以滑鼠右鍵按一下資料行標籤,然後選取 [顯示資料行] > [其他動作],以開啟捷徑功能表。 (如果您關閉了 [Just My Code],您就不會看到這個命令。)隨即出現第三個名為 [其他動作] 的資料行。

    Screenshot of Additional Actions column.

    Screenshot of Additional Actions column.

    針對此資料行中顯示 [當在使用者程式碼中未處理時繼續] 的例外狀況,如果未在使用者程式碼中處理該例外狀況,但是在外部處理,則偵錯工具會繼續。

  2. 若要變更特定例外狀況的此設定,請選取例外狀況,以滑鼠右鍵按一下以顯示捷徑功能表,然後選取 [當在使用者程式碼中未處理時繼續]。 您也可以變更整個例外狀況類別的設定 (例如整個 Common Language Runtime 例外狀況)。

    Screenshot of Continue when unhandled in user code setting.

    Screenshot of Continue when unhandled in user code setting.

例如,ASP.NET Web 應用程式將例外狀況轉換成 HTTP 500 狀態碼 (在 ASP.NET Web API 中的例外狀況處理)) 加以處理,這可能無法幫助您判斷例外狀況的來源。 在下列範例中,使用者程式碼會呼叫擲回 String.Format()FormatException。 執行中斷,如下所示:

Breaks on user-unhandled exception

新增及刪除例外狀況

您可以新增及刪除例外狀況。 若要從類別中刪除例外狀況類型,請選取例外狀況,然後在 [例外狀況設定] 工具列上,選擇 [從清單中刪除選取的例外狀況] 按鈕 (減號)。 或者,您可以使用滑鼠右鍵按一下例外狀況,然後從捷徑功能表中選取 [刪除]。 刪除例外狀況與核取例外狀況有相同的效果,也就是偵錯工具並不會在其擲回時中斷。

若要新增例外狀況:

  1. 在 [例外狀況設定] 視窗中,選取其中一個例外狀況類別 (例如,[Common Language Runtime] )。

  2. 選擇 [將例外狀況新增至選取的類別] 按鈕 (加號)。

    Screenshot of Add an exception to the selected category button.

    Screenshot of Add an exception to the selected category button.

  3. 輸入例外狀況的名稱 (例如 System.UriTemplateMatchException)。

    Screenshot of Type exception name.

    Screenshot of Type exception name.

    此例外狀況隨即加入清單 (依字母順序),且會自動核取。

若要將例外狀況新增至 [GPU 記憶體存取例外狀況]、[JavaScript 執行階段例外狀況] 或 [Win32 例外狀況] 類別,請包含錯誤碼和描述。

提示

請檢查您的拼字! [例外狀況設定] 視窗並不會檢查新增的例外狀況是否存在。 因此如果您鍵入 Sytem.UriTemplateMatchException,您會得到針對該例外狀況 (而非針對 System.UriTemplateMatchException) 的項目。

例外狀況設定會保存在此方案的 .suo 檔案中,因此可套用至特定的方案中。 您無法在不同方案間重複使用特定的例外狀況設定。 現在,只會保存已新增的例外狀況;但已刪除的例外狀況除外。 您可以加入例外狀況,關閉並重新開啟方案,然後該例外狀況仍不會消失。 但是,如果您刪除例外狀況,然後關閉/重新開啟此方案,則該例外狀況會重新出現。

[例外狀況設定] 視窗在 C# 中支援泛型例外狀況類型,但在 Visual Basic 中不支援。 若要中斷類似 MyNamespace.GenericException<T>的例外狀況,您必須新增例外狀況為 [MyNamespace.GenericException'1] 。 也就是說,如果您已經建立類日此程式碼的例外狀況:

public class GenericException<T> : Exception
{
    public GenericException() : base("This is a generic exception.")
    {
    }
}

您可以使用先前的程序,將例外狀況新增至 [例外狀況設定]

Screenshot of Add generic exception.

Screenshot of Add generic exception.

將條件新增至例外狀況

使用 [例外狀況設定] 視窗來設定例外狀況的條件。 目前支援的條件包括例外狀況要包含或排除的模組名稱。 您可以將模組名稱設定為條件,選擇只在特定程式碼模組上中斷例外狀況。 您也可以選擇避免在特定模組上中斷。

注意

從 Visual Studio 2017 開始,支援將條件新增至例外狀況。

若要新增條件式例外狀況:

  1. 選擇 [例外狀況設定] 視窗中的 [編輯條件] 按鈕,或以滑鼠右鍵按一下例外狀況,然後選擇 [編輯條件]

    Screenshot of exception conditions.

  2. 若要將額外的必要條件新增至例外狀況,請針對每個新條件選取 [新增條件]。 隨即出現其他條件行。

    Screenshot of extra conditions for an exception.

  3. 針對每個條件行,輸入模組的名稱,並將比較運算子清單變更為 EqualsNot Equals。 您可以在名稱中指定萬用字元 (\*) 來指定多個模組。

  4. 如果您需要刪除條件,請選擇條件行結尾的 X