2016-03-21 2 views
-1

Я пытаюсь выяснить, как правильно обращаться с некоторыми исключениями в задаче:Как правильно обрабатывать исключения задач

Вызов метода:

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(), который выходит из строя из-за исключения, игнорируется, и поэтому он не нарушает мой код?

UPDATE: Стек трассировки для InnerException в System.AggregateException ("Удаленный сервер возвратил ошибку:. (500) Внутренняя ошибка сервера")

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 
+0

Каковы детали исключения для 'AggregateException', которые вы видите? –

+0

Ваш метод не обрабатывает все исключения. Допустим, что 'branch3gInfo' имеет значение NULL. Вы получите NRE, который затем будет передан вызывающему методу. Подробнее см. Свойство 'AggregateException.InnerExceptions'. –

+0

@StephenCleary Он содержит одно InnerException, в котором говорится, что HTTP-вызов возвратил HTTP 500 (Internal Server Error). Я обновил вопрос о трассировке стека. – blgrnboy

ответ

3

Вы можете видеть из своего стека вызовов:

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

, что это вызов GetBranch3GInterfacesAsync, который не работает, а не вызов GetRouterExtendedInfoFromInterfaceAsync. GetBranch3GInterfacesAsync вызывается вне блока try, поэтому, естественно, будет распространяться исключение.

+0

Не следует использовать попытку/улов в вызывающем методе 'try { Task.WaitAll (discoveryRouterExtendedInfoTask, getActive3GRoutersTask); } ' заботиться о том, чтобы поймать исключение? – blgrnboy

+0

@blgrnboy: он будет поднят там, и он будет повторно поднят, если вы вызовете 'getActive3GRoutersTask.Result'. –

Смежные вопросы