デバッグSystem.AggregateException-これは、非同期コードでは真でもあります

名前が示すように、単一のバッチ内の1つのまたは複数の異常のためAggregateException例外を示唆しています。ときに、この例外が発生した理由をこの記事では、私が表示されます、だけでなく、Cのコードでそれをデバッグする方法。

生成および処理エラー

私たちは、から始めることを余儀なく新しいAggregateExceptionを生成してみましょう。この例外は広く、.NETのタスク・ライブラリーで使用されている、なぜサンプルを選択することは簡単な作業であるタスクが含まれています。

タスクTASK1 = Task.Factory.StartNew(()=> { スロー 新しい)(ArgumentExceptionがします;});
タスクタスク2 = Task.Factory.StartNew(()=> { スロー 新しい)(UnauthorizedAccessExceptionを;});

試します
{
    Task.WaitAll(TASK1、タスク2)。
}
キャッチ(AggregateException AE)
{
}

上記の例では、我々は二つのタスクを実行し、各タスクは、例外がスローされます。WaitAllを呼び出すことによって、我々は呼んで、これら二つのタスクの結果を待つために.NETを教えてください。タスクの2つの組み合わせた結果がAggregateExceptionになります。

このエラーのデバッグ

異常は、我々はInnerExceptionsのプロパティでスローされた2つの例外を参照してくださいデバッガからの例:

 

約束の名前、AggregateException他の異常のラッパーとして。この例では、ArgumentExceptionがUnauthorizedAccessException内部異常として使用することができます。 次のようにいくつかのケースでは、あなたは、各Aキャッチブログの例外を追加します。
試します
{
    ...
}
キャッチ(ArgumentExceptionがEX1)
{
    // ログおよび再スロー
}
 キャッチ(UnauthorizedAccessExceptionのEX2)
{
    // ログとツバメ 
}

このように、あなたは唯一の再スローまたはそれらの第三に、ユーザーの個々のレコード例外にエラーメッセージを生成することができます。AggregateExceptionではなく、各例外にInnerExceptionsのプロパティで循環するよりも、ハンドルという名前の便利な小さなヘルパーメソッドを提供します。

試します
{
    ...
}
キャッチ(AggregateException AE)
{
    ae.Handle(内側 =>
    {
        // ログインナー
        ...
         リターンインナーはありUnauthorizedAccessException。
    });
}

本実施例では、各例外を記録する方法を扱います。各例外の処理かどうかを示す、ブール値を返すFUNCニーズ。この例では、UnauthorizedAccessExceptionにハンドルアプローチを伝えるが、ArgumentExceptionが対応していません。これはAggregateExceptionになりますが呼び出し元のコードに背を投げますが、ことInnerExceptionsプロパティなしUnauthorizedAccessException(私たちは、この異常処理されたとしてマークされているため)。

HttpClientをからAggregateExceptions

System.Net.Http.HttpClientクラスを扱うには、あなたはAggregateExceptionが発生することがあります。これは主に非同期コード(待ち、ContinueWith、など)のための古いAPIの使用です。例で見てみましょう:
試します
{
    VARクライアント= 新しいHttpClientを();
    VaRのタスク= client.GetStringAsync(" https://httpstat.us/500 " );
    task.Wait();
    VaRの結果= task.Result。
}
キャッチ(AggregateException EX)
{
    スローEXを。
}

HTTPステータスコード500を返すためHttps://httpstat.us/500要求は、コードがHttpRequestExceptionスローします。私は、例としてGetStringAsync方法を使用するが、他の非同期メッセージ(例えばPostAsync)場合、コードは非常に似て見えます。AggregateException例外に包装taskapi、上述したように、例外は、HTTP InnerExceptionsプロパティに含まれています。

実際の例外を取得するには、オプションの範囲を持っています。私は例外をログに記録する必要性を説明するために再利用されます。私は前の例でお見せしたハンドルの方法でレッツスタート:

試します
{
    ...
}
キャッチ(AggregateException EX)
{
    ex.Handle(内側 =>
    {
        もし(内側があるHttpRequestException)
        {
            // 例外ログ
            
            返す ;
        }
        
        リターン はfalse ;
    });
}

私は内部例外をチェックすると、この場合には、TELLハンドルメソッド例外が処理された、HttpRequestExceptionタイプです。他のシナリオでは、私は(偽を返すことによって)元の例外を再スローハンドルを伝えます。
もう一つの方法は、ContinueWith AggregateExceptionをキャプチャし、処理するための方法を使用することです:

VARクライアント= 新しいHttpClientを();
VaRのタスク= クライアント
    .GetStringAsync(" https://httpstat.us/500 " 
    .ContinueWith(T =>
    {
        試します
        {
            返すt.Resultを。
        }
        キャッチ(AggregateException EX)
        {
            ex.Handle(内側 =>
            {
                もし(内側があるHttpRequestException)
                {
                    // 例外ログ

                    返す ;
                }

                リターン はfalse ;
            });
        }
        キャッチ(例外の例)
        {
            スローEXを。
        }

        リターン ヌル
    });
task.Wait();
VaRの結果= task.Result。
私は基本的にただのtry-catchをContinueWithメソッドから外に移動します。

あなたが.NET4.5(ない場合は、おそらく、それがあるべき)である場合は最後に、あなたはのawaitキーワードを使用することができます。

VARクライアント= 新しいHttpClientを();
試します
{
    VaRの結果= のawait client.GetStringAsync(" https://httpstat.us/500 " );
}
キャッチ(HttpRequestException EX)
{
    // ログ例外
}
 キャッチ(例外の例)
{
    スローEXを。
}

コードではなくAggregateExceptionのHttpRequestExceptionを撮影しているかに注意してください。.NETが自動的に開いAggregateException意志と根本的な例外が発生するためです。ほとんどの場合、これはあなたが望むものです。別の給付のawaitキーワード非同期使用する既存のコードを移植します。

おすすめ

転載: www.cnblogs.com/yilang/p/12563904.html