1. ホーム
  2. c#

[解決済み] タスクの例外は、タスクの待ち時間やExceptionプロパティへのアクセスでは観測されませんでした。その結果、観測されなかった例外は

2022-12-05 17:52:18

質問

これは何を意味し、どのように解決すればよいのでしょうか。

TPLタスクを使っています。

エラーの全体像

あるタスクの例外が、そのタスクの待ち時間やExceptionプロパティへのアクセスによって観測されませんでした。その結果、観測されなかった例外はファイナライザースレッドによって再スローされました。

at System.Threading.Tasks.TaskExceptionHolder.Finalize()

mscorlib

どのように解決するのですか?

タスクを作成した後、一度も task.Wait() を呼び出したり、その結果を取得したりすることはありません。 Task<T> を実行すると、タスクがガベージコレクタに回収されるときに、 アプリケーションを最終的に破棄することになります。 詳しくは、MSDN の TPL における例外処理 .

ここでの最良の選択肢は、例外を "handle"することです。 タスクに継続をアタッチし、発生した例外をログに記録したり、飲み込んだりすることができます。 これは、タスクの例外を記録するきれいな方法を提供し、単純な拡張メソッドとして記述することができます。

public static void LogExceptions(this Task task)
{
    task.ContinueWith( t =>
    {
         var aggException = t.Exception.Flatten();
         foreach(var exception in aggException.InnerExceptions)
             LogException(exception);
    }, 
    TaskContinuationOptions.OnlyOnFaulted);
}

以上により、任意のタスクがアプリをティアリングダウンするのを防ぎ、それをログに記録することができます。

Task.Factory.StartNew( () => 
   { 
       // Do your work...
   }).LogExceptions();

別の方法として TaskScheduler.UnobservedTaskExceptionを購読することもできます。 をサブスクライブして、そこで処理することもできます。