【问题标题】:How to return the not-cancelled tasks from Task.WhenAll execution如何从 Task.WhenAll 执行中返回未取消的任务
【发布时间】:2021-12-03 05:45:21
【问题描述】:

我有一个可取消的任务列表;他们有他们的CancellationTokenSource。他们的取消独立于其他人。我想从Task.WhenAll返回所有未取消的任务。

var tasks = new List<Task<string>>();

/** some code here **/

var done = await Task.WhenAll(tasks); // This throws an OperationCanceledException,
                                      // when at least one task is cancelled.

StackOverflow中有问题“如何在任务中取消任务”,但这里的问题不是那个。

【问题讨论】:

  • 正如in the previous post 所说,您不能使用单个 CancellationToken 来做到这一点。每个任务都需要一个。
  • 您的意思是取消前已经完成的任务?
  • @gunr2171 每个任务我已经有一个取消源,我希望每个任务都抛出 OperationCanceledException。本题的要求是如何在Task、WhenAll或其他方式中处理,只处理未取消的任务
  • @the.Doc 之前和之后,请考虑以下任务:t1、t2、t3、t4。它们在某种意义上是独立的,它们有自己的 CancellationTokenSource,但它们在设计上会抛出 OperationCanceledException。可以说t2被取消了。我希望能够完成 t1,t2,t3,t4。
  • tasks.Where(t =&gt; !t.IsCanceled) 有什么问题

标签: c# async-await task-parallel-library cancellation-token


【解决方案1】:

你可以通过循环Task.WhenAll来重试其余的任务

var tasks = new List<Task<string>>();

/** some code here **/
var notCanceled = tasks;
do
{
    try
    {
        await Task.WhenAll(notCanceled);
        break;
    }
    catch (OperationCanceledException)
    {
        notCanceled = notCanceled.Where(t => !t.IsCanceled).ToArray();
    }
} while (notCanceled.Any())

【讨论】:

    【解决方案2】:

    一种方法是将Task.WhenAll 任务存储在Task 变量中,这样您就可以添加一个专门处理IsCanceled 情况的catch 块。

    var tasks = new List<Task<string>>();
    
    /** some code here **/
    
    Task whenAll = Task.WhenAll(tasks);
    Task<string>[] successfullyCompletedTasks;
    
    try
    {
        await whenAll;
        successfullyCompletedTasks = tasks.ToArray();
    }
    catch when (whenAll.IsCanceled)
    {
        successfullyCompletedTasks = tasks.Where(t => !t.IsCanceled).ToArray();
    }
    
    // Make sure that our assumptions do not contradict the reality
    Debug.Assert(successfullyCompletedTasks.All(t => t.IsCompletedSuccessfully));
    

    【讨论】:

      猜你喜欢
      • 2015-02-02
      • 1970-01-01
      • 2022-12-23
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 2020-08-05
      • 1970-01-01
      相关资源
      最近更新 更多