gpt4 book ai didi

c# - 编写一个 Task.WhenAll/WhenAny 变体,取消第一个故障/取消任务上的所有其他任务

转载 作者:行者123 更新时间:2023-12-05 05:27:01 25 4
gpt4 key购买 nike

我是 C# 的新手,今天开始使用 TPL。我决定写一个修改版本任务 Task.WhenAll 作为练习。我希望它具有以下行为:

  • 找到第一个出现故障或被取消的任务后,取消其余任务,而不是等待它们完成。
  • 如果任务出错,返回的任务应该有正确的异常集(即不会被继续吞没并替换为 OperationCancelledException())
  • 方法签名中没有异步(希望避免冒泡)。

我想出了以下无效的疯狂/愚蠢的代码片段,我很难想象发生了什么。我无法想象会发生任何阻塞,我设想发生的是一系列任务,每个任务都在等待其余任务完成。谁能解释一下这是怎么回事?

我不会在生产代码中使用它,这只是为了测试我的基础知识。我意识到一种更简单的方法是执行 Task.WhenAll 并让列表中的任务本身具有在失败时取消的延续。

    public static Task WhenAllError(List<Task> tasks, CancellationToken ct)
{
var tcs = new TaskCompletionSource<object>();
return Task.WhenAny(tasks).ContinueWith<Task>((t) =>
{
if (tasks.Count == 0)
{
tcs.SetResult(null);
return tcs.Task;
}

if (t.IsFaulted)
{
Console.WriteLine("Task faulted. Cancelling other tasks: {0}", t.Id);
cts.Cancel();
// Make sure the tasks are cancelled if necessary
tcs.SetException(t.Exception);
return tcs.Task;
}
// Similarly handle Cancelled

tasks.Remove(t);
return WhenAllError(tasks, ct);
}).Unwrap();
}

最佳答案

CancellationToken类没有 Cancel 方法。你需要一个 CancellationTokenSource能够取消 CancellationToken

同样,要影响任务的结果,您需要一个 TaskCompletionSource,您不能安全地取消已经运行的任务。看这个post

关于c# - 编写一个 Task.WhenAll/WhenAny 变体,取消第一个故障/取消任务上的所有其他任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22399063/

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