2016-03-21 131 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,OR,應該抓住例外。爲什麼調用方法拋出System.AggregateException如果我在GetBranch3GInformationAsync()中處理這個?

我該如何解決這個問題,以便任何因異常而失敗的呼叫GetRouterExtendedInfoFromInterfaceAsync()都被忽略,並且不會破壞我的代碼?

UPDATE:

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'爲空。你會得到NRE,然後傳播到調用方法。有關更多詳細信息,請參閱'AggregateException.InnerExceptions'屬性。 –

+0

@StephenCleary它包含一個InnerException,它表示HTTP調用返回HTTP 500(內部服務器錯誤)。我更新了堆棧跟蹤的問題。 – blgrnboy

回答

3

您可以從您的調用堆棧看到:

: 在 System.AggregateExceptionInnerException( 「(500)內部服務器錯誤遠程服務器返回錯誤」)堆棧跟蹤
at CASpectrumApi.Managers.CasApiServiceManager.<GetBranch3GInterfacesAsync>d__34.MoveNext() 

它是致電GetBranch3GInterfacesAsync失敗,而不是致電GetRouterExtendedInfoFromInterfaceAsync。在try塊之外調用GetBranch3GInterfacesAsync,所以自然異常會傳播。

+0

不應該調用方法中的try/catch 'try Task.WaitAll(discoverRouterExtendedInfoTask,getActive3GRoutersTask); }' 照顧捕捉異常? – blgrnboy

+0

@blgrnboy:它會在那裏被提升,如果你調用'getActive3GRoutersTask.Result',它將被重新提升。 –