数年前に実装された私のベース ViewModel は、UI の応答性を維持しながらタスクを実行するためのこの拡張メソッドを提供します*:
protected void Work(Action job)
{
IsBusy = true;
var stackTrace = new StackTrace();
var task = Task.Factory.StartNew(job)
.ContinueWith(failedTask => HandleException(failedTask, stackTrace),
TaskContinuationOptions.OnlyOnFaulted)
.ContinueWith(_ => { IsBusy = false; });
}
void HandleException(Task task, StackTrace stackTrace)
{
Dispatcher.BeginInvoke(
() => { throw new Exception(task.Exception.InnerException.ToString() +
stackTrace); });
}
IsBusy
進行状況バーを表示するために UI から監視されるプロパティです。
背後にある考え方HandleExceptions
は、それらが監視されてから UI スレッドにスローされtry/catch
、メソッド内のブロックによってキャッチされMain()
、ユーザーにわかりやすいメッセージを表示してアプリを安全に閉じる前にログに記録されるというものです。ログに呼び出し元の情報が含まれるように、stackTrace が渡されます。
ただし、最近、次の Windows ダイアログで、ログもわかりやすいメッセージも表示されずにアプリケーションがクラッシュするというレポートを受け取り始めました。
Windows イベント ログを見ると、次の EventData が得られました。
アプリケーション: xxxxApplication.Loader.exe
フレームワークのバージョン: v4.0.30319
説明: 未処理の例外が発生したため、プロセスが終了しました。
例外情報: System.AggregateException
スタック: System.Threading.Tasks.TaskExceptionHolder.Finalize() で
私は何か悪いことをしていContinueWith()
ますか?
タスクの例外が何らかの形で監視されない可能性はありますか?
*: については知っていBackgroundWorker
ます。これはおそらく当時はより良いアイデアのように見えたか、追加の利点がありました.