Consider the following C# code:
CancellationTokenSource tCancelSource = new CancellationTokenSource();
var tTask = Task.Factory.StartNew
(
() =>
{
// Start child
Task.Factory.StartNew
(() =>
{
Thread.Sleep(2000);
Console.WriteLine("A");
tCancelSource.Token.ThrowIfCancellationRequested();
}
, tCancelSource.Token
, TaskCreationOptions.AttachedToParent
, TaskScheduler.Current
)
.ContinueWith
(
t =>
{
Console.WriteLine("B");
}
, tCancelSource.Token, TaskContinuationOptions.AttachedToParent
, TaskScheduler.Current
);
}
, tCancelSource.Token, TaskCreationOptions.PreferFairness
, TaskScheduler.Current
)
.ContinueWith
(t => Console.WriteLine("C"));
Thread.Sleep(500);
tCancelSource.Cancel();
tTask.Wait();
Console.WriteLine("Done"); Console.Read();
子任务的继续未能触发,即控制台未打印出B。注释掉取消调用将会打印出B。
观察到:
A
C
预期
A
B
C
似乎如果取消了父任务,则不会触发子任务的继续执行,但是我找不到这方面的文档说明。有人知道原因或者在哪里可以找到相关文档吗?
编辑:
我忘记将取消标记传递给最终的继续执行任务。实际上,我找到的文档中写到:“[...]如果先决条件已被取消,则不会启动后续执行任务”,但是我被TaskContinuation.OnlyOnCanceled选项所迷惑。例如,这种情况是可能的。
CancellationTokenSource tSource = new CancellationTokenSource();
Task tTest = Task.Factory.StartNew
(
() =>
{
throw new Exception("foobar");
}, tSource.Token).ContinueWith(t =>
{
Console.WriteLine("A " + t.Status);
}
, tSource.Token
, TaskContinuationOptions.NotOnFaulted
, TaskScheduler.Current
)
.ContinueWith
(
t =>
{
Console.WriteLine("B " + t.Status);
}
, tSource.Token
);
tTest.Wait();
Console.Read();
第一个继续项设置为已取消状态(因为其TaskContinuationOptions值导致其不运行),但令牌未被设置为已取消状态。因此,最后一个继续项在此处运行。