子がアタッチされている場合の.netタスクの動作を理解しようとしています。
私は次のテストコードを持っています:
void Test()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Task child = null;
var parent = Task.Factory.StartNew(() =>
{
child = Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested)
Thread.Sleep(100);
token.ThrowIfCancellationRequested();
}, token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
}, token);
Thread.Sleep(500);
Debug.WriteLine("State of parent before cancel is {0}", parent.Status);
Debug.WriteLine("State of child before cancel is {0}", child.Status);
tokenSource.Cancel();
Thread.Sleep(500);
Debug.WriteLine("State of parent is {0}", parent.Status);
Debug.WriteLine("State of child is {0}", child.Status);
}
この結果は次のとおりです。
State of parent before cancel is WaitingForChildrenToComplete
State of child before cancel is Running
A first chance exception of type 'System.OperationCanceledException' occurred in mscorlib.dll
State of parent is RanToCompletion
State of child is Canceled
Canceled
両方のタスクがトークンを共有し、子がアタッチされている場合でも、親タスクの状態は明らかになりません。
Canceled
キャンセルが発生したときに親タスクを復帰状態にするにはどうすればよいですか?
注例外をスローすると、両方のタスクが戻りFaulted
ます。
これは、MSDNに記載されている予想される動作です。親タスクは、子タスクを待機する必要があります(キャンセルセクションまでスクロールダウンします)。親タスクは、すべての良性の障害(キャンセルなど)を処理する必要があります。
親タスクを失敗させるには、トークンを待って渡すだけです。
Task child = null;
var parent = Task.Factory.StartNew(() =>
{
child = Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested) Thread.Sleep(100);
token.ThrowIfCancellationRequested();
}, token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
// This is the magic line.
child.Wait(token);
}, token);
このコードを使用して、テストだけでなく生産的な処理を行う場合は、の代わりにデリゲートTask.Run()
をサポートする簡略化されたコードの使用も検討する必要があります。この記事は非常に興味深いものです。async
Task.Factory.StartNew()
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加