分析 API 的例外處理
例外狀況告知是所有告知中最難以描述和理解的。 本主題說明例外狀況處理並解釋分析 API 如何處理各種類型的例外狀況。
例外狀況告知流程圖
例外狀況處理本質上很複雜。 本主題中說明的例外狀況告知提供了複雜分析工具所需的所有資訊,以便追蹤行程 (搜尋階段或回溯階段)、框架、filter,以及為分析處理序中的每個執行緒所執行的 finally 區塊。 例外狀況告知不會提供任何 ThreadID,但是您可以呼叫 ICorProfilerInfo::GetCurrentThreadID 方法,探索哪個 Managed 執行緒已擲回例外狀況。
下列圖表顯示程式碼分析工具在監視例外狀況事件時,如何接收各種回呼。 每個執行緒都是在一般執行狀態中開始。 當執行緒處在例外狀況系統內的狀態 (在搜尋階段或回溯階段中) 時,它是由例外狀況系統控制。 當執行緒處在其中一種狀態時,發生的任何非例外狀況相關的回呼 (例如,ICorProfilerCallback::ObjectAllocated) 都會歸屬於例外狀況系統本身。 當執行緒處在例外狀況系統外的狀態時,它是執行任意 Managed 程式碼。
例外狀況回呼順序
巢狀例外狀況
當處理例外狀況時,跨入 Managed 程式碼的執行緒可能會擲回另一個例外狀況,而造成全新的例外狀況處理行程 (這個新行程由上面圖表中的「新的例外處理行程」表示)。如果這種巢狀例外狀況逸出原始例外狀況的 filter/finally/catch 區塊,這會影響原始例外狀況,如下:
如果巢狀例外狀況發生在 filter 區塊內並逸出 filter 區塊,則 filter 會被視為傳回 false,而且第一個行程會繼續。
如果巢狀例外狀況發生在 finally 區塊內並逸出 finally 區塊,則原始例外狀況絕不會繼續處理。
如果巢狀例外狀況發生在 catch 區塊內並逸出 catch 區塊,則原始例外狀況絕不會繼續處理。
Unmanaged 處理常式
例外狀況可能會在 Unmanaged 程式碼中處理。 在這種情況下,分析工具會看到回溯階段,但不會接收 catch 處理常式的告知。 Unmanaged 程式碼中會繼續正常執行。 感知 Unmanaged 程式碼的分析工具將能偵測這個狀況,但僅限 Managed 的分析工具可能會看到任意數目的項目,包括 (但不限於) 下列:
當 Unmanaged 程式碼呼叫或回到 Managed 程式碼時的 ICorProfilerCallback::UnmanagedToManagedTransition 回呼。
執行緒結束 (如果 Unmanaged 程式碼是在執行緒的根目錄)。
應用程式結束 (如果 Unmanaged 程式碼結束應用程式)。
CLR 處理常式
例外狀況可能由 Common Language Runtime (CLR) 本身處理。 在這種情況下,分析工具會看到回溯階段,但不會接收 catch 處理常式的告知。 它會看到 Managed 或 Unmanaged 程式碼中繼續正常執行。
未處理的例外狀況
根據預設,未處理的例外狀況會導致 .NET Framework 2.0 版中的處理序終止。 您可以藉由使用應用程式相容性旗標 (如 Managed 執行緒中的例外狀況中所述),強制遵循 .NET Framework 第 1 版的例外狀況原則。