gpt4 book ai didi

c# - 为什么取消父任务时不会触发子任务的任务继续?

转载 作者:行者123 更新时间:2023-11-30 15:43:03 24 4
gpt4 key购买 nike

考虑以下 C# 代码:

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 不会打印到控制台。注释掉对 Cancel 的调用将打印 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 值导致它不运行),而没有将 token 设置为已取消。所以最后一个延续确实在这里运行。

最佳答案

最终,如果子任务附加到其父任务,则它依赖于它,并且由于您使用的是相同的取消 token ,因此您可以预料到这种行为。您可以使用单独的取消 token ,但我认为您需要处理冒泡取消异常以维持流程 - 另一种选择是分离任务。

您可能想查看 herehere有关取消的文档。

关于c# - 为什么取消父任务时不会触发子任务的任务继续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7093651/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com