如何正确处理任务异常

时间:2016-03-21 17:07:41

标签: c# parallel-processing task

我想弄清楚如何正确处理任务中的一些异常:

通话方式:

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;

var branch3gInfo = getActive3GRoutersTask.Result;会抛出System.Aggregate Exception

被叫方法:

public async Task<Branch3GInfo> GetBranch3GInformationAsync(int searchDepth)
{
    var branch3gInfo = await GetBranch3GInterfacesAsync();

    var activeRoutersExtInfos = new List<CasApiRouterModelExtendedInfo>();
    foreach (var netInterface in branch3gInfo.Branch3GActiveInterfaces)
    {
        try
        {
            var task = GetRouterExtendedInfoFromInterfaceAsync(netInterface, searchDepth);
            var result = await task;

            if (task.Status == TaskStatus.RanToCompletion && result != null)
            {
                activeRoutersExtInfos.Add(result);
            }
            else
            {
                Trace.TraceError("Error occured trying to get info about Active 3G Router " + netInterface.ModelName + ".");
            }
        }
        catch (Exception ex)
        {
            Trace.TraceError("Error occured trying to get info about Active 3G Router " + netInterface.ModelName +
                ": \n" + ex.Message);
        }

    }

    return new Branch3GInfo()
    {
        Branch3GActiveInterfaces = branch3gInfo.Branch3GActiveInterfaces,
        Branch3GCapableInterfaces = branch3gInfo.Branch3GCapableInterfaces,
        Branch3GActiveRouters = activeRoutersExtInfos.ToArray()
    };
}

从我的代码中,我假设GetBranch3GInformationAsync()应该执行else子句,而不是将结果添加到activeRoutersExtInfos,或者它应该是捕捉异常。如果我在System.AggregateException中处理此问题,为什么调用方法会抛出GetBranch3GInformationAsync()

如何修复此问题,以便忽略因异常而失败的GetRouterExtendedInfoFromInterfaceAsync()的任何调用,以便它不会破坏我的代码?

更新: InnerExceptionSystem.AggregateException的堆栈跟踪(&#34;远程服务器返回错误:(500)内部服务器错误。&#34;)

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

1 个答案:

答案 0 :(得分:3)

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

at CASpectrumApi.Managers.CasApiServiceManager.<GetBranch3GInterfacesAsync>d__34.MoveNext()

调用GetBranch3GInterfacesAsync失败,而不是调用GetRouterExtendedInfoFromInterfaceAsync。 <{1}}在GetBranch3GInterfacesAsync块之外被调用,因此异常会自然传播。