4

アプリケーションで Task を使用するためのテストを行っています。今、私は次のことを行いました:

var task = Task.Factory.StartNew(() => {
   // long running process
   throw new Exception("test"); // throwing TestException
});
task.ContinueWith(x => MyErrorHandler(task.Exception), TaskContinuationOptions.OnlyOnFaulted);

void MyErrorHandler(Exception error) {
   MessageBox.Show(error.Message);
}

アイデアは、長時間実行されるプロセスが実行され、ユーザーが UI をブロックすることなく作業できるようにすることです。問題 (例外) があった場合は、長時間実行されているプロセスが終了した後に表示されます (通常の場合、例外はありません)。

これは私が使用した正しい方法ですか、それとも別の方法で行う必要がありますか? この方法で取得でき、現在は表示されていない問題はありますか?

4

1 に答える 1

8

を明示的にチェックTask.Exceptionしているため、これは機能し、例外が監視されないようにします。

ここでいくつかの推奨事項を示します。

まず、これが本当に長時間実行されるタスクである場合は、次のように指定することをお勧めします。

var task = Task.Factory.StartNew(() => {
   // long running process
   throw new Exception("test"); // throwing TestException
}, TaskCreationOptions.LongRunning);

第二に、次のクロージャーは必要ありませんtask

// use x.Exception, since x is the task
task.ContinueWith(x => MyErrorHandler(x.Exception), TaskContinuationOptions.OnlyOnFaulted);

これをメイン スレッドで実行することもできます。特に、(UI で) より複雑なレポートを使用することにした場合は、次のようにします。

// This will work if MyErrorHandler uses a UI control, since it'll marshal back to the current synchronization context
task.ContinueWith(x => MyErrorHandler(x.Exception), 
    CancellationToken.None,
    TaskContinuationOptions.OnlyOnFaulted,
    TaskScheduler.FromCurrentSynchronizationContext());

(これは、エラー ハンドラで UI コントロールなどを使用する場合にのみ必要です。)

また、.NET 4.5 または .NET 4 用の async ターゲット設定パックを使用している場合は、new async/ awaitsupport を使用してこれを簡素化できます。メソッドに としてフラグを立てるとasync、次のことができます。

try
{
    await Task.Factory.StartNew(() => {
           // long running process
           throw new Exception("test"); // throwing TestException
        }, TaskCreationOptions.LongRunning);
}
catch(Exception error)
{
      MyErrorHandler(error);
}
于 2013-02-13T17:46:34.027 に答える