これは何を意味し、どのように解決しますか?
TPLタスクを使用しています。
エラー全体
タスクの待機は、タスクで待機することも、Exceptionプロパティにアクセスすることもできませんでした。その結果、監視されていない例外がファイナライザスレッドによって再スローされました。
System.Threading.Tasks.TaskExceptionHolder.Finalize()で
mscorlib
これは何を意味し、どのように解決しますか?
TPLタスクを使用しています。
エラー全体
タスクの待機は、タスクで待機することも、Exceptionプロパティにアクセスすることもできませんでした。その結果、監視されていない例外がファイナライザスレッドによって再スローされました。
System.Threading.Tasks.TaskExceptionHolder.Finalize()で
mscorlib
回答:
タスクを作成し、task.Wait()
の結果を呼び出したり取得しようとしたりしないTask<T>
場合、ガベージコレクターによってタスクが収集されると、ファイナライズ中にアプリケーションが破棄されます。詳細については、TPLの例外処理に関するMSDNのページを参照してください。
ここでの最良のオプションは、例外を「処理」することです。これは継続を介して行うことができます-タスクに継続をアタッチし、発生した例外をログ/スワロー/などに記録できます。これにより、タスクの例外をログに記録するクリーンな方法が提供され、単純な拡張メソッドとして記述できます。
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をサブスクライブしてそこで処理することもできます。
.Net 4.0
。例外処理は、アプリケーションを破棄しないようにデフォルトで変更されまし.net 4.5
た。詳細については、.NET 4.5のタスク例外処理を参照してください
承知しました; これは、Task
ガベージコレクションに任された後でファイナライズされたが、タスク自体が失敗したことを意味します。2つの修正があります。
ContinueWith(...)
購読すると、チェック.IsFaulted
して.Exception
上Task
のパラメータで)TaskScheduler.UnobservedTaskException
イベントを処理し、監視済みとしてマークします(e.SetObserved()
エラーを記録した後に呼び出します)IsFaulted
だけの場合は、OnlyOnFaulted
継続オプションを使用して手動での確認を回避できます...
SetObserved
にUnobservedTaskExceptionEventArgs
呼び出す必要があります。
これを試してください:
public static void ThrowFirstExceptionIfHappens(this Task task)
{
task.ContinueWith(t =>
{
var aggException = t.Exception.Flatten();
foreach (var exception in aggException.InnerExceptions)
{
throw exception; // throw only first, search for solution
}
},
TaskContinuationOptions.OnlyOnFaulted); // not valid for multi task continuations
}
public static Task CreateHandledTask(Action action)
{
Task tsk = Task.Factory.StartNew(action);
tsk.ThrowFirstExceptionIfHappens();
return tsk;
}
Off
は、任意の4文字の単語として名前が付けられたクラスに静的スタブメソッドを用意し、これをキャッチオール継続に使用します。この特定の例外によるうんざりした欲求不満のいくつかを解消するのに役立ちます。