TPL で例外処理を集中化するために使用できるオプションが 2 つあります。 1. タスク スケジューラの監視されていないタスク例外イベントを使用します。2.フォルト状態のタスクの継続の使用。
タスク スケジューラの監視されていないタスクの例外イベントの使用。
タスク スケジューラには、演算子 += を使用してサブスクライブできる UnobservedTaskException イベントがあります。
- 注 1: ハンドラーの本体では、 UnobservedTaskExceptionEventArgs 引数で SetObserved() を呼び出して、例外が処理されたことをスケジューラーに通知する必要があります。
- 注 2: ハンドラーは、タスクがガベージ コレクターによって収集されたときに呼び出されます。
- 注 3: タスクを待機する場合でも、try/catch ブロックによって待機を保護する必要があります。
- 注 4: .Net 4.0 と 4.5 の未処理のタスク例外の既定のポリシーは異なります。
概要: このアプローチは、ファイア アンド フォーゲット タスクや、一元化された例外処理ポリシーから逃れた例外のキャッチに適しています。
障害状態のタスクの継続の使用。
TPL を使用すると、アタッチ アクションと継続オプションを取るメソッド ContinueWith() を使用して、タスクにアクションをアタッチできます。このアクションは、オプションで指定された場合にのみ、タスクの終了後に呼び出されます。特に:
t.ContinueWith(c => { /* exception handling code */ },
TaskContinuationOptions.OnlyOnFaulted);
Task t に例外処理コードを含む継続をインストールします。このコードは、未処理の例外が原因でタスク t が終了した場合にのみ実行されます。
- 注 1: 例外処理コードで例外値を取得します。そうしないと、泡が出ます。
- 注 2: 例外処理コードは、タスクの終了直後に呼び出されます。
- 注 3: 例外が例外処理コードで取得された場合、それは処理済みと見なされ、タスク待機中の try/catch ブロックはそれをキャッチできません。
Task から継承されたカスタム Task を使用し、継続によって例外ハンドラーを追加した方が、集中型の例外処理に適していると思います。また、タスク スケジューラの Unobserved Task Exception イベントを使用して、カスタマイズされていないタスクを使用しようとする試みをキャッチすることにより、このアプローチに付随します。