【问题标题】:Cancelling a task throws 'A task was cancelled' AggregateException. Why? [closed]取消任务会引发“任务已取消”AggregateException。为什么? [关闭]
【发布时间】:2021-07-21 18:54:48
【问题描述】:

我创建了一个简单的 TaskManager,用于跟踪正在运行的任务及其取消标记。我的代码 sn-p 使用它来取消指定的任务,然后等待它们完成。直截了当,我的代码几乎可以正常工作。

代码中无法解释的部分是Task.WaitAll 调用。它会抛出一个AggregateException,其中包含三个“任务已取消”内部异常。这当然是真的,但是为什么它会抛出异常呢?代码如下:

internal void StopProcessor()
{       
    try
    {   
        var taskList = _taskManager.CancelTask(new string[] { "InboundProcessor", "OutboundProcessor", "MainProcessor" });
        
        Task.WaitAll(taskList, 2000);
    }
    catch (Exception)
    {
        foreach (var t in _taskManager.GetAllTasks())
        {
            Console.WriteLine($"Task ID={t.Task.Id}, status={t.Task.Status}, cancelled={t.Task.IsCanceled}, completed={t.Task.IsCompleted}, faulted={t.Task.IsFaulted}");
        }
    }
}

当我检查 catch 块中的任务状态详细信息时,我得到了我预期的结果,所有任务都有一个 status=cancelled,completed=True 并且没有错误:

  • 任务 ID=17,状态=取消,取消=真,完成=真,故障=假

  • 任务 ID=19,状态=取消,取消=真,完成=真,故障=假

  • 任务 ID=21,状态=取消,取消=真,完成=真,故障=假

我不明白这种行为的原因,有人可以教育我并告诉我如何改进此代码吗?谢谢。

【问题讨论】:

  • 取消几乎总是作为例外出现,因为它不是预期的成功结果;如果可以取消,这应该只是意料之中
  • 请注意,它的行为也完全符合as documented: "(Throws) AggregateException: 至少有一个 Task 实例被取消。如果任务被取消,则 AggregateException 异常在其 InnerExceptions 中包含 OperationCanceledException 异常集合。-或- 在至少一个 Task 实例的执行过程中引发了异常。"
  • (所以我不认为这真的无法解释。它可以通过“按预期工作”来解释,即使这不是“在阅读文档之前按预期工作”。)

标签: c# task-parallel-library


【解决方案1】:

From the Microsoft documentation

AggregateException
至少有一个任务实例被取消。如果任务被取消,则 AggregateException 异常在其 InnerExceptions 集合中包含 OperationCanceledException 异常。

-或-

在至少一个 Task 实例的执行过程中引发了异常。

【讨论】:

    猜你喜欢
    • 2011-11-12
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多