Managed 執行緒中的例外狀況Exceptions in Managed Threads

從 .NET Framework version 2.0 開始,通用語言執行平台允許執行緒中大多數未處理的例外狀況自然地繼續。Starting with the .NET Framework version 2.0, the common language runtime allows most unhandled exceptions in threads to proceed naturally. 在大多數情況下,這表示未處理的例外狀況導致應用程式終止。In most cases this means that the unhandled exception causes the application to terminate.

注意

這是 .NET Framework 1.0 和 1.1 的重大變更,其針對許多未處理的例外狀況提供了防護網 — 例如,執行緒集區執行緒中的例外狀況。This is a significant change from the .NET Framework versions 1.0 and 1.1, which provide a backstop for many unhandled exceptions — for example, unhandled exceptions in thread pool threads. 請參閱本主題後面的從舊版變更See Change from Previous Versions later in this topic.

通用語言執行平台針對用於控制程式流程的特定未處理例外狀況提供了防護網︰The common language runtime provides a backstop for certain unhandled exceptions that are used for controlling program flow:

  • 因為呼叫了 Abort,而導致執行緒中擲回 ThreadAbortExceptionA ThreadAbortException is thrown in a thread because Abort was called.

  • 因為正在卸載執行緒執行所在的應用程式定義域,而在執行緒中擲回 AppDomainUnloadedExceptionAn AppDomainUnloadedException is thrown in a thread because the application domain in which the thread is executing is being unloaded.

  • 通用語言執行平台或主機處理序會藉由擲回內部例外狀況來終止執行緒。The common language runtime or a host process terminates the thread by throwing an internal exception.

如果在通用語言執行平台所建立的執行緒中有上述任何未處理的例外狀況,則此例外狀況會終止執行緒,但通用語言執行平台不允許例外狀況進一步繼續作業。If any of these exceptions are unhandled in threads created by the common language runtime, the exception terminates the thread, but the common language runtime does not allow the exception to proceed further.

如果未在主要執行緒中,或在從 Unmanaged 程式碼進入執行平台的執行緒中處理這些例外狀況,這些例外狀況會正常進行,而導致應用程式終止。If these exceptions are unhandled in the main thread, or in threads that entered the runtime from unmanaged code, they proceed normally, resulting in termination of the application.

注意

在任何 Managed 程式碼有機會安裝例外狀況處理常式之前,執行平台可能會擲回未處理的例外狀況。It is possible for the runtime to throw an unhandled exception before any managed code has had a chance to install an exception handler. 即使 Managed 程式碼沒有機會處理這類例外狀況,但允許例外狀況自然地進行。Even though managed code had no chance to handle such an exception, the exception is allowed to proceed naturally.

公開開發期間的執行緒問題Exposing Threading Problems During Development

若允許執行緒以無訊息模式失敗,而不終止應用程式,則可能偵測不到嚴重的程式設計問題。When threads are allowed to fail silently, without terminating the application, serious programming problems can go undetected. 這是長時間執行的服務和其他應用程式特有的問題。This is a particular problem for services and other applications which run for extended periods. 因為執行緒失敗,所以程式狀態會逐漸變差。As threads fail, program state gradually becomes corrupted. 應用程式效能可能會降低,或應用程式可能會停止回應。Application performance may degrade, or the application might become unresponsive.

允許執行緒中的未處理例外狀況自然地進行,直到作業系統終止程式,公開開發和測試期間的這類問題為止。Allowing unhandled exceptions in threads to proceed naturally, until the operating system terminates the program, exposes such problems during development and testing. 程式終止的錯誤報告可支援偵錯。Error reports on program terminations support debugging.

從舊版變更Change from Previous Versions

最重大的變更與 Managed 執行緒有關。The most significant change pertains to managed threads. 在 .NET Framework 1.0 和 1.1 版中,通用語言執行平台會針對下列情況中未處理的例外狀況提供防護網:In the .NET Framework versions 1.0 and 1.1, the common language runtime provides a backstop for unhandled exceptions in the following situations:

  • 執行緒集區執行緒上不會有未處理的例外狀況。There is no such thing as an unhandled exception on a thread pool thread. 當工作擲回未處理的例外狀況時,執行平台會將例外狀況堆疊追蹤列印到主控台,然後將執行緒傳回到執行緒集區。When a task throws an exception that it does not handle, the runtime prints the exception stack trace to the console and then returns the thread to the thread pool.

  • 使用 Thread 類別的 Start 方法建立的執行緒上不會有未處理例外狀況之類的項目。There is no such thing as an unhandled exception on a thread created with the Start method of the Thread class. 在此種執行緒上執行的程式碼擲回未處理的例外狀況時,執行平台會將例外狀況堆疊追蹤列印到主控台,然後正常終止執行緒。When code running on such a thread throws an exception that it does not handle, the runtime prints the exception stack trace to the console and then gracefully terminates the thread.

  • 完成項執行緒上不會有未處理的例外狀況。There is no such thing as an unhandled exception on the finalizer thread. 當完成項擲回未處理的例外狀況時,執行平台會將例外狀況堆疊追蹤列印到主控台,然後允許完成項執行緒繼續執行完成項。When a finalizer throws an exception that it does not handle, the runtime prints the exception stack trace to the console and then allows the finalizer thread to resume running finalizers.

Managed 執行緒的前景或背景狀態不會影響此行為。The foreground or background status of a managed thread does not affect this behavior.

若為源自於 Unmanaged 程式碼的執行緒上未處理的例外狀況,差別更加細微。For unhandled exceptions on threads originating in unmanaged code, the difference is more subtle. 對於已通過機器碼之執行緒上的 Managed 例外狀況或原生例外狀況而言,執行階段 JIT-attach 對話方塊的順序優先於作業系統對話方塊。The runtime JIT-attach dialog preempts the operating system dialog for managed exceptions or native exceptions on threads that have passed through native code. 在所有情況下,此處理序會終止。The process terminates in all cases.

移轉程式碼Migrating Code

一般而言,變更會公開先前無法辨識的程式設計問題,以便修正這些問題。In general, the change will expose previously unrecognized programming problems so that they can be fixed. 不過,在某些情況下,程式設計人員可能已利用執行階段防護網來終止執行緒。In some cases, however, programmers might have taken advantage of the runtime backstop, for example to terminate threads. 視情況而定,它們應該考慮下列其中一個移轉策略︰Depending on the situation, they should consider one of the following migration strategies:

  • 重新建構程式碼,讓執行緒在收到訊號時依正常程序結束。Restructure the code so the thread exits gracefully when a signal is received.

  • 使用 Thread.Abort 方法來中止執行緒。Use the Thread.Abort method to abort the thread.

  • 如果執行緒必須停止,處理序終止作業才能繼續,請讓執行緒成為背景執行緒,以便在處理序結束時自動終止。If a thread must be stopped so that process termination can proceed, make the thread a background thread so that it is automatically terminated on process exit.

在所有情況下,此策略應該遵循例外狀況的設計方針。In all cases, the strategy should follow the design guidelines for exceptions. 請參閱例外狀況的設計方針See Design Guidelines for Exceptions.

應用程式相容性旗標Application Compatibility Flag

系統管理員可以在應用程式組態檔的 <runtime> 區段中放置相容性旗標,做為暫存的相容性度量。As a temporary compatibility measure, administrators can place a compatibility flag in the <runtime> section of the application configuration file. 這會導致通用語言執行平台還原為 1.0 和 1.1 版的行為。This causes the common language runtime to revert to the behavior of versions 1.0 and 1.1.

<legacyUnhandledExceptionPolicy enabled="1"/>  

主機覆寫Host Override

在 .NET Framework 2.0 版中,Unmanaged 主機可以使用裝載 API 中的 ICLRPolicyManager 介面,覆寫通用語言執行平台的預設未處理例外狀況原則。In the .NET Framework version 2.0, an unmanaged host can use the ICLRPolicyManager interface in the Hosting API to override the default unhandled exception policy of the common language runtime. Iclrpolicymanager:: Setunhandledexceptionpolicy 函數用來設定未處理例外狀況的原則。The ICLRPolicyManager::SetUnhandledExceptionPolicy function is used to set the policy for unhandled exceptions.

另請參閱See also