マネージド スレッドの例外Exceptions in Managed Threads

.NET Framework バージョン 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 が呼び出されたため、スレッドで ThreadAbortException がスローされる。A ThreadAbortException is thrown in a thread because Abort was called.

  • スレッドが実行中のアプリケーション ドメインがアンロードされると、スレッドで AppDomainUnloadedException がスローされる。An 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.

メイン スレッドまたはアンマネージ コードからランタイムに入ったスレッドでこれらの例外がハンドルされない場合、例外は通常どおり続行するため、アプリケーションが終了します。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.

注意

マネージド コードが例外ハンドラーをインストールする機会を得る前に、ランタイムはハンドルされない例外をスローできます。It is possible for the runtime to throw an unhandled exception before any managed code has had a chance to install an exception handler. マネージド コードにこのような例外をハンドルする機会がない場合でも、例外を続行させることができます。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

最も重要な変更は、マネージド スレッドに関する変更です。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.

マネージド スレッドのフォアグラウンドまたはバックグラウンドのステータスは、この動作に影響しません。The foreground or background status of a managed thread does not affect this behavior.

アンマネージ コードで作成されたスレッドのハンドルされない例外の場合、微妙な相違点があります。For unhandled exceptions on threads originating in unmanaged code, the difference is more subtle. ランタイムの JIT アタッチ ダイアログは、ネイティブ コードを通ってきたスレッド内でのマネージド例外またはネイティブ例外に関する、オペレーティング システム ダイアログより優先されます。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 では、アンマネージ ホストはホスト 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