在等待带有 AggregateExceptions 的故障任务时保留异常详细信息
异步编程通常涉及等待任务。 但是,当任务失败并包含 AggregateException
时,标准 await
运算符仅重新抛出第一个异常,可能会丢失关键的诊断信息。本文详细介绍了一个强大的解决方案,可以准确处理和保留 AggregateException
.
挑战在于保留原始的AggregateException
,同时仍然使用await
的便利性。 虽然 try-catch
块似乎就足够了,但更优雅且信息丰富的解决方案更好。 创建自定义等待者是可能的,但会增加不必要的复杂性。
考虑这个演示问题的示例:
<code class="language-csharp">static async Task Run() { Task[] tasks = new[] { CreateTask("ex1"), CreateTask("ex2") }; await Task.WhenAll(tasks); } static Task CreateTask(string message) { return Task.Factory.StartNew(() => { throw new Exception(message); }); }</code>
在 Run
中,尽管底层任务中发生了两个异常,但仅重新抛出了一个异常。
解决方案利用了扩展方法:
<code class="language-csharp">public static async Task HandleAggregateExceptions(this Task source) { try { await source.ConfigureAwait(false); } catch (Exception ex) { // Check for null Exception in case of cancellation if (source.Exception == null) throw; // ExceptionDispatchInfo preserves the original exception's stack trace. ExceptionDispatchInfo.Capture(source.Exception).Throw(); } }</code>
此 HandleAggregateExceptions
扩展方法可确保 AggregateException
内的所有异常都正确重新抛出,保留其原始堆栈跟踪。这有利于彻底的错误处理并简化调试。 使用此方法,调用 await tasks.HandleAggregateExceptions();
将提供完整的异常详细信息。
以上是如何在不丢失异常详情的情况下准确地等待任务并处理聚合异常?的详细内容。更多信息请关注PHP中文网其他相关文章!