C# 如何正确处理任务异常

C# 如何正确处理任务异常,c#,parallel-processing,task,C#,Parallel Processing,Task,我试图找出如何正确处理任务中的某些异常: Task<Branch3GInfo> getActive3GRoutersTask = Task.Run( () => CAS.Service.GetBranch3GInformationAsync(3) ); try { Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask); } catch(Aggregat

我试图找出如何正确处理任务中的某些异常:

Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;
调用方法:

Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;
根据我的代码,我假设GetBranch3GInformationAsync应该执行else子句,该子句不会将结果添加到ActiveRoutersExpireFos,或者,它应该捕获异常。如果我在GetBranch3GInformationAsync中处理这个问题,为什么调用方法会抛出System.AggregateException

Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;
我如何着手解决这个问题,以便忽略由于异常而失败的对GetRouterExtendedInfoFromInterfaceAsync的任何调用,并且不会破坏我的代码

Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;
更新: System.AggregateException中InnerException的堆栈跟踪远程服务器返回错误:500内部服务器错误

Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult) 
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CASpectrumApi.CasApiRestCall.<ExecuteAsync>d__38.MoveNext() in C:\src\CASpectrumApi\src\CASpectrumApi\Queries\CasApiRestCall.cs:line 294
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CASpectrumApi.Managers.CasApiServiceManager.<RenderAndExecuteRestCallAsync>d__103.MoveNext() in C:\src\CASpectrumApi\src\CASpectrumApi\Managers\CasApiServiceManager.cs:line 2516
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CASpectrumApi.Managers.CasApiServiceManager.<QueryModelsFilterByAttributeNotDeviceOnlyAsync>d__51.MoveNext() in C:\src\CASpectrumApi\src\CASpectrumApi\Managers\CasApiServiceManager.cs:line 1196
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CASpectrumApi.Managers.CasApiServiceManager.<GetBranch3GInterfacesAsync>d__34.MoveNext() in C:\src\CASpectrumApi\src\CASpectrumApi\Managers\CasApiServiceManager.cs:line 442
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at CASpectrumApi.Managers.CasApiServiceManager.<GetBranch3GInformationAsync>d__26.MoveNext() in C:\src\CASpectrumApi\src\CASpectrumApi\Managers\CasApiServiceManager.cs:line 246

您可以从调用堆栈中看到:

Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;
at CASpectrumApi.Managers.CasApiServiceManager.<GetBranch3GInterfacesAsync>d__34.MoveNext()

失败的是对GetBranch3GInterfacesAsync的调用,而不是对GetRouterExtendedInfoFromInterfaceAsync的调用。GetBranch3GInterfacesAsync在try块外调用,因此异常自然会传播。

您看到的AggregateException的异常详细信息是什么?您的方法没有处理所有异常。假设branch3gInfo为null。您将获得NRE,然后将其传播到调用方法。有关详细信息,请参阅AggregateException.InnerExceptions属性。@StephenCleary它包含一个InnerException,表示HTTP调用返回HTTP 500内部服务器错误。我已经更新了堆栈跟踪的问题。调用方法try{Task.WaitAlldiscoverRouterExtendedInfoTask,getactive3groutrstask;}中的try/catch不应该捕获异常吗?@blgrnboy:它将在那里引发,如果调用getactive3groutrstask.Result,它将重新引发。
Task<Branch3GInfo> getActive3GRoutersTask = 
    Task.Run(
        () => CAS.Service.GetBranch3GInformationAsync(3)
    );

try
{
    Task.WaitAll(discoverRouterExtendedInfoTask, getActive3GRoutersTask);
}
catch(AggregateException aggEx)
{
    StringBuilder sb = new StringBuilder();
    sb.Append("Some problems occured on GetNodesInCriticalCondition(): \n");
    foreach (var ex in aggEx.InnerExceptions)
    {
        sb.Append(ex.Message);
    }

    Trace.TraceError(sb.ToString());
}

var branch3gInfo = getActive3GRoutersTask.Result;