【问题标题】:When can an AggregateException contain more than 1 inner exception?AggregateException 何时可以包含超过 1 个内部异常?
【发布时间】:2012-04-11 17:37:17
【问题描述】:

我对 .NET 任务并行库的错误处理有疑问。在哪些情况下,AggregateException 会持有超过 1 个内部异常?我知道这可能发生在前。在调用Task.WaitAll(anArrayOfTasks) 时,有 2 个或更多任务抛出异常,但是否还有其他情况(即,如果只等待 1 个任务完成,是否有可能得到超过 1 个内部异常)?

【问题讨论】:

  • 与并行库无关。假设您有一个删除文件列表的方法,但有些文件被锁定了。您可以使用AggregateException 重新抛出锁定的文件并继续删除其余文件。

标签: .net exception task-parallel-library


【解决方案1】:

如果您有一个“父”任务和一个或多个附加到父任务的“子”任务,就会发生这种情况。这意味着父任务只有在其所有子任务完成并且子任务的异常也传播到父任务时才会完成。

以下面的代码为例:

var task = Task.Factory.StartNew(
    () =>
    {
        Task.Factory.StartNew(
            () => { throw new Exception("inner"); },
            TaskCreationOptions.AttachedToParent);

        throw new Exception("outer");
    });

如果你在那个任务上Wait(),它会抛出一个AggregateException,看起来像这样:

  • AggregateException
    • Exception:外层
    • AggregateException
      • Exception:内部

如果你不喜欢它可以在AggregateExceptions 中包含AggregateExceptions,你可以使用the Flatten() method。还有另一种方法可以用来处理AggregateExceptions:Handle()

【讨论】:

  • 感谢您的回答,+1 提到了 Handle() 方法,我不知道。
【解决方案2】:

一个任务可以引发一个聚合异常,该异常本质上可以包含多个内部异常。这意味着在处理任务时,您应该始终考虑具有多个内部异常的聚合异常。即使您没有使用 Task.WaitAll,您正在等待的任务也可能在内部等待多个子任务。或者,您等待的任务可能会返回多个异常。作为呼叫者,您根本无法知道。

【讨论】:

  • 我同意在一般情况下,您应该假设您可能会得到一个异常列表并设计您的错误处理,我只想知道是否处理一个不依赖的异步任务在其他异步任务上将永远创建一个超过 1 个异常被传递的情况。
  • 可能,只是可能。不过可能性不大。如果内部任务等待多个子任务。将创建一个新的 AggregateException,其中包含 1 个 AggregateException,其中包含多个(可能是聚合的!)内部异常。因此,在 AggregateException 上调用 Flatten 方法以获取所有异常并将它们作为集合处理总是一个好习惯
  • 在这种情况下,您将如何将错误传递给 UI?通常,如果执行一个操作,您可以有两种结果,成功或错误。在我看来,设计一个隐式处理错误列表的 UI 似乎令人困惑,并且有两种情况(一种用于一个错误,一种用于多个错误)似乎使事情过于复杂。我一直在考虑在 UI 中最多处理 1 个异常,并记录所有异常(并向用户显示一条消息以检查错误日志)。
  • 这是一个有效的问题。走向异步意味着,如果一个分支失败,您可以精确地采取行动,而不是拥有 havign 线性代码的奢侈,您有多个代码分支同时执行,其中每个分支都可能最终处于未预料到的状态(例外) 并且您必须从所有这些中恢复。异常处理并不像显示一个消息框那么简单。如果您的下载操作在中间失败怎么办。插座是否关闭?如果 2 次异步下载操作失败怎么办?我建议您根据异步原则重新考虑您的设计
  • 我提出了一个我想要实现的过于简化的版本,但是,我可能会根据每个案例来处理异常,因为异步场景中的异常处理太复杂而无法找到银子子弹为它。
猜你喜欢
  • 2020-08-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多