C# 如何在不触发取消本身的情况下处理已取消的任务?
我试图让C#中的任务为特定用例工作,但我不理解任务延续选项如何影响任务流 我想做的是用ContinueWith将一系列任务链接在一起。这将看起来像这样: A->B->C->D 但是,我想包括在发生错误时使其短路的选项,因此它应该如下所示: A->B->C->D->X 所以我把“OnlyOnRanToCompletion”作为每个ContinueWith函数的任务延续选项。然后,为了捕获取消并返回错误,我将最后一个任务放在链的末尾,任务继续选项设置为“onlyoncancelled” 问题是,当命中最后一个块时,不满足“继续”选项,并且即使原始任务系列从未取消,任务也会被设置为“取消” 我想做的是运行A到D,如果其中一个导致取消,则跳过其余部分并运行X。如果A到D完成,任务不应取消。该解决方案需要支持任意数量的continuation,并且将使用LINQ.Expressions创建,因此除非创造性地使用async/await,否则可能无法运行 展示这一点的一些示例代码是:C# 如何在不触发取消本身的情况下处理已取消的任务?,c#,task-parallel-library,C#,Task Parallel Library,我试图让C#中的任务为特定用例工作,但我不理解任务延续选项如何影响任务流 我想做的是用ContinueWith将一系列任务链接在一起。这将看起来像这样: A->B->C->D 但是,我想包括在发生错误时使其短路的选项,因此它应该如下所示: A->B->C->D->X 所以我把“OnlyOnRanToCompletion”作为每个ContinueWith函数的任务延续选项。然后,为了捕获取消并返回错误,我将最后一个任务放在链的末尾,任务继续选项设置为“onlyoncancelled” 问题是,当命
var cts = new CancellationTokenSource();
var token = cts.Token;
var t = Task.FromResult(1)
.ContinueWith(
x => x.Result + 1,
token,
TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default)
.ContinueWith(
x => x.Result + 1,
token,
TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default)
.ContinueWith(
x => -1,
token,
TaskContinuationOptions.OnlyOnCanceled,
TaskScheduler.Default);
这里的预期行为是返回3,状态为not completed
实际结果是任务被取消
我该怎么做
另外,我不能使用
async
,因为我的目标是在从LINQ.Expressions编译的内容中使用TPL,这样它就可以异步计算并在结束时处理错误,而不会引发任何异常。有关此行为的解释,请参阅ContinueWith
的备注:
在当前任务完成之前,不会计划执行返回的任务。如果不满足通过continuationOptions参数指定的条件,则将取消继续任务而不是计划任务
由于未满足上次调用<代码>继续的条件,因此从该调用返回的<代码>任务<代码>被取消。解决了这个问题-要让上次继续运行,无论以前的继续是否已完成,并且不将状态设置为已取消,请执行以下操作:
TaskContinuation.None
,这样它将始终运行,因此如果它以完成状态到达此处,它将不会取消您应该真正使用
await
,而不是ContinueWIth
来构建异步工作流<代码>等待更易于使用,并且在许多领域都有更理想的默认行为,特别是在错误处理方面,正如您在这里看到的。我应该将此添加到问题中-如果我能够,我会,但我不能。我正在使用LINQ.Expressions编译一个需要异步运行的小程序,我没有访问权限。我强烈怀疑这一点,但如果您不打算提供有关实际问题的足够信息,那么人们就不能给你一个好的解决方案了。这是真的:通过一个命名的异步方法和一个简单调用它的lambda,这个问题很容易就被解决了。再说一次,如果你不描述你的实际问题,那么你就无法得到很好的解决方案。