これを達成する方法について、MSDN にもここにも具体的な言及はありません。ユースケースはややあいまいですが、それでも有効だと思います。
var cancel = new CancellationTokenSource();
var task = Task.Factory.StartNew(() => { Task.Delay(1000, cancel.Token).Wait(); }, cancel.Token);
cancel.CancelAfter(100);
task.Wait();
上記のコードは、切り離された子遅延タスクtask
を含むを 100 ミリ秒後にキャンセルしようとし、 (キャンセルにより)が生成されるのを待ちます。これに関する問題は、キャンセルではなくフォルトになることです。両方が同じキャンセル トークンを共有しているにもかかわらず、遅延タスクが親にアタッチされていないため、これは予想される動作です。task
AggregateException
task
task
私の質問は、特に、Task.Delay
既に実行されているタスクに a をアタッチする方法に関連しています。親タスクにアクセスできる場合でも、これを行うことは可能ですか? それが不可能な場合、または親タスク インスタンスにアクセスできない場合、このシナリオを処理する適切な方法は何ですか?
私が思いついた最善の回避策は、遅延タスクWait
を try/finally ブロックでラップし、タスクのキャンセルを明示的にバブルアップしようとすることでした。
try { Task.Delay(1000, cancel.Token).Wait(); } finally { cancel.Token.ThrowIfCancellationRequested(); }
効果的ではありますが、あまり正しくはありませんが、これを達成するためのより良い方法があるかどうかはわかりません. 望ましい結果は、キャンセルが発生した場合Canceled
ではなく、親タスクが移動することです。Faulted
そのため、切り離された子タスクでキャンセルの発生が発生した場合でも、親タスクは に移行する必要がありCanceled
ます。
注:問題や結果が変わらないように見えるという理由だけで、ここでは意図的に async/await を省略しました。そうでない場合は、例を示してください。