共用方式為


例外狀況概觀

更新:2007 年 11 月

例外狀況是執行程式時遭遇的任何錯誤情況或意料不到的行為。由於程式碼或所呼叫的程式碼 (例如,共用程式庫) 中有錯誤、找不到可用的作業系統資源、Common Language Runtime 遭遇非預期的意外情況 (例如,無法驗證程式碼) 等情況,就可能會發生例外狀況。您的應用程式可以從這某些情況復原,但從其他的則不行。雖然您可以從大部分應用程式例外狀況復原,但您無法從大部分執行階段例外狀況復原。

在 .NET Framework 中,例外狀況是繼承自 Exception 類別的物件。例外狀況會從問題發生的程式碼區域擲回。例外狀況會在堆疊中往上傳遞,直到應用程式處理它或程式結束為止。如需使用 .NET Framework 處理例外狀況的詳細資訊,請參閱 Exception 類別主題的內容。

執行階段如何管理例外狀況

執行階段根據例外狀況物件和程式碼保護區塊來使用例外處理模型。Exception 物件在例外狀況發生時被建立以表示它。

執行階段會為各個可執行檔建立例外狀況資訊表格。可執行檔的各個方法在例外狀況資訊表中具有例外處理資訊的相關陣列 (可以是空白的)。陣列的各個項目會描述程式碼的保護區塊、與那程式碼相關的任何例外狀況篩選條件,和任何例外處理常式 (Catch 陳述式)。這個例外狀況表格非常有效率,並且例外狀況未發生時,在處理器時間或記憶體使用方面沒有效能減損。您只有在例外狀況發生時會使用資源。

例外狀況資訊表顯示保護區塊的例外處理常式的四種類型:

  • 每當區塊結束 (不論經由一般控制流程或因為未處理的例外狀況而發生) 都會執行的 Finally 處理常式

  • 如果例外狀況發生,但未在一般控制流程完成時執行,必定會執行的 Fault 處理常式

  • 按類型篩選的處理常式,處理指定類別或其任何衍生類別的任何例外狀況

  • 使用者篩選的處理常式,執行使用者指定的程式碼以判斷例外狀況是否應該藉由處理常式來處理,或應該傳遞至下一個保護區塊

各個語言都依照其規格實作這些例外處理常式。例如,Visual Basic 2005 會透過 Catch 陳述式中的變數比較 (使用 When 關鍵字),提供對使用者篩選處理常式的存取,C# 則不實作使用者篩選處理常式。

當例外狀況發生時,執行階段開始兩階段的程序:

  1. 執行階段在陣列搜尋第一個保護區塊:

    • 保護含有目前執行中指令

    • 含有例外處理常式或含有篩選條件 (以處理例外狀況) 的區域

  2. 如果有相符的狀況發生,執行階段會建立 Exception 物件以描述例外狀況。執行階段接著執行例外狀況發生的陳述式和處理例外狀況的陳述式之間的所有 Finally 或 Fault 陳述式。請注意,例外處理常式的順序也是十分重要的:越位於內層的例外處理常式會優先進行評估。也請注意,例外處理常式可以存取攔截例外狀況的常式的區域變數和區域記憶體,但任何在例外狀況擲回時產生的中繼值會遺失。

    如果在目前方法中沒有相符狀況發生,執行階段會搜尋目前方法的各個呼叫端,並且在堆疊中一路向上繼續搜尋。如果沒有符合的呼叫端,執行階段即允許偵錯工具來存取例外狀況。如果偵錯工具並未附加至例外狀況,執行階段會引發 UnhandledException 事件。如果沒有 UnhandledException 事件的接聽程式 (Listener),執行階段會傾印堆疊追蹤並結束程式。

篩選執行階段例外狀況

您可以藉著型別,或者藉著使用者定義的準則,篩選您要攔截和處理的例外狀況。

按類型篩選的處理常式處理特定例外狀況的類型 (或從它衍生的類別)。按類型篩選的例外處理常式的最常見形式是指定僅只攔截例外狀況的特定類別。

下列範例顯示設計來攔截特定例外狀況 (在此例中為 FileNotFoundException) 的例外處理常式。

Catch e As FileNotFoundException
   Console.WriteLine("[Data File Missing] {0}", e)
catch(FileNotFoundException e) {
    Console.WriteLine("[Data File Missing] {0}", e);
}

使用者篩選的例外處理常式根據您對例外狀況定義的需求,攔截並處理例外狀況。這些處理常式會在 Visual Basic 2005 使用 Catch 陳述式配合 When 關鍵字。如需以這種方式篩選例外狀況的詳細資訊,請參閱 HOW TO:使用 Catch 區塊中的特定例外狀況

請參閱

概念

Exception 類別和屬性

例外狀況階層架構

處理例外狀況的最佳作法

其他資源

例外處理基礎觀念

處理和擲回例外狀況