写任务.当第一个出错/被取消的任务时取消所有其他任务的变量



我对c#相当陌生,今天开始使用TPL。我决定写一个修改版本的任务任务。WhenAll作为练习。我希望它具有以下行为:

  • 在发现第一个出现故障或被取消的任务后,取消其余的任务,而不是等待它们完成。
  • 如果任务出错,返回的任务应该有正确的异常设置(即不通过继续吞下并替换为OperationCancelledException()))
  • 方法签名中没有async(想要避免冒泡)。

我想出了下面这段疯狂/愚蠢的代码,它不起作用,我很难想象发生了什么。我无法想象会有任何阻塞发生,我所想象的是一连串的任务,每个任务都在等待其他任务完成。有人能解释一下这是怎么回事吗?

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

    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取消正在运行的任务。看这篇文章

最新更新