ホームページ >バックエンド開発 >C++ >例外の詳細を失わずにタスクを正確に待機し、AggregateExceptions を処理するにはどうすればよいですか?

例外の詳細を失わずにタスクを正確に待機し、AggregateExceptions を処理するにはどうすればよいですか?

DDD
DDDオリジナル
2025-01-12 15:55:43959ブラウズ

How Can I Accurately Await Tasks and Handle AggregateExceptions Without Losing Exception Details?

AggregateExceptions で失敗したタスクを待機するときに例外の詳細を保持する

非同期プログラミングには、待機中のタスクが含まれることがよくあります。 ただし、タスクが失敗し、AggregateException が含まれている場合、標準の await 演算子は最初の例外のみを再スローするため、重要な診断情報が失われる可能性があります。この記事では、AggregateException.

内のすべての例外を正確に処理して保存するための堅牢なソリューションについて詳しく説明します。

課題は、AggregateException の利便性を利用しながら、元の await を維持することにあります。 try-catch ブロックで十分だと思われるかもしれませんが、より洗練された有益なソリューションの方が望ましいでしょう。 カスタム awaiter を作成することは可能ですが、不必要な複雑さが追加されます。

問題を示す次の例を考えてみましょう:

<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 では、基になるタスクで 2 つの例外が発生しているにもかかわらず、再スローされる例外は 1 つだけです。

このソリューションでは拡張メソッドを利用します:

<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(); を呼び出すと、完全な例外の詳細が提供されます。

以上が例外の詳細を失わずにタスクを正確に待機し、AggregateExceptions を処理するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。