在等待帶有 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中文網其他相關文章!