なぜTask.ContinueWith()
メソッドが必要なのですか。その「継続コード」をタスク本体の中に書くことはできませんか?
3 に答える
サーシャゴールドシュタインの答えは正しいです。'continue'構成コードがタスクに直接アクセスできない、またはタスクの実行方法を設定しない場合があります。たとえば、タックを集約したいプラガブルシステム。
ただし、適用される可能性のある別の理由があります。粒度
TaskCreationOptions.LongRunningの使用を誘発する可能性のある要件を検討してください。何百ものプロセスがスケジュールされ、実行され、完了している並列システムでは、タスクスケジューラは、タスクをスケジュールするときに効率的なプロセッサアフィニティを促進するように機能しています。
タスクをきめ細かいサブタスクに分割してチェーンできる状況にある場合は、TaskCreationOptions.LongRunningを使用する必要がなくなります。簡単に言うと、4つのコアしか使用できない環境で、10個の大きなタスクを同時に実行するようにスケジュールするよりも、100個の小さなタスクを同時に終了するようにスケジュールする方が簡単であるため、パフォーマンスが向上します。連鎖タスクは、先行する直後に開始することが保証されていないことに注意してください。
これは興味深い質問であり、スケーラブルなシステムが必要な場合にのみ問題になります。
私に尋ねる場合は、アプリの拡張に役立つため、可能な場合はContinueWith()を使用する必要があります。
時々、あなたは外部からタスクを受け取り、あなたの継続をそれに連鎖させたいと思うことがあります。アクションなしでタスクを作成する方法もあります(たとえば、TaskCompletionSourceを使用)。
タスクの継続により、タスクのチェーンを作成できます。チェーン内の各タスクの後には、他の1つのタスクが続きます。
また、メソッドでは、ターゲットが完了したとき、またはエラーが発生したときに、Task.ContinueWith
非同期でチェックすることができますTask
TaskContinuationOptions
Task
Task task = Task.Factory.StartNew
(
() =>
{
//Your action when the task started
}
);
task.ContinueWith
(
_ =>
{
//Your action when the task completed
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent,
TaskScheduler.FromCurrentSynchronizationContext()
);
task.ContinueWith
(
(t) =>
{
//Action when error occured
Exception exception = null;
if (t.Exception.InnerException != null)
{
exception = t.Exception.InnerException;
}
else
{
exception = t.Exception;
}
//You can use this exception
},
CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent,
TaskScheduler.FromCurrentSynchronizationContext()
);
詳細については、こちらをご覧ください