2012-03-27 112 views
8

所有,關於上述主題有很多問題,但我相信這是完全不同的,以保證新的問題。我有以下Task和延續處理各種任務Status; TaskStatus.RanToCompletion,TaskStatus.Canceled,當然還有AggregateException,通過TaskStatus.Faulted。代碼看起來像TPL和異常處理

Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
    asyncMethod(uiScheduler, token, someBoolean), token); 

asyncTask.ContinueWith(task => 
{ 
    // Check task status. 
    switch (task.Status) 
    { 
     // Handle any exceptions to prevent UnobservedTaskException.    
     case TaskStatus.RanToCompletion: 
      if (asyncTask.Result) 
      { 
       // Do stuff... 
      } 
      break; 
     case TaskStatus.Faulted: 
      if (task.Exception != null) 
       mainForm.progressRightLabelText = task.Exception.InnerException.Message; 
      else 
       mainForm.progressRightLabelText = "Operation failed!"; 
     default: 
      break; 
    } 
} 

這一切運作良好,但我擔心我是否沒有我這樣做的權利,因爲有一個AggregateException的可能性延續中被甩出 - 然後呢?

我不想Wait在我的asyncTask也不延續,因爲這將阻止返回到UI線程。爲了趕上延續內拋出的異常不能意味着我必須做這樣的事情肯定

Task parentTask = Task.Factory.startNew(() => 
    { 
     Task<bool> asyncTask = Task.Factory.StartNew<bool>(() => 
      asyncMethod(uiScheduler, token, someBoolean), token); 

     Task continueTask = asyncTask.ContinueWith(task => 
      { 
       // My continuation stuff... 
      } 

     try 
     { 
      continueTask.Wait(); 
     } 
     catch(AggregateException aggEx) 
     { 
      // Some handling here... 
     } 
    }); 

這會甚至工作?這裏最好的做法是什麼?

一如既往,感謝您的時間。

+0

我見過任務「跑到完成」,實際上他們拋出一個AggregateException。這種錯誤處理不起作用。爲什麼不使用try/catch? – 2012-03-27 09:52:26

+0

您的意思是在後臺線程或實際延續委託方法中調用的方法中? – MoonKnight 2012-03-27 09:53:03

回答

12

可以使用傳統的try/catch您的代表留意AggregateException內或者您也可以將永遠只能運行,如果前因已經使用TaskContinuationOptions.OnlyOnFaulted選項故障的具體延續鏈。後一種方法允許定義非常乾淨的任務工作流程。例如:

Task myRootTask = ....; 

myRootTask.ContinueWith(rootAntecdent => 
{ 
    // this will only be executed if the antecedent completed successfully, no need to check for faults 
}, 
TaskContinuationOptions.OnlyOnRanToCompletion); 

myRootTask.ContinueWith(rootAntecedent => 
{ 
    // this will only be executed if the antecedent faulted, observe exception and handle accordingly 
}, 
TaskContinuationOptions.OnlyOnFaulted); 
2

MSDN有一個相當寫得很好「如何」主題:here

你會發現他們只是使用try/catch(AggregateException)塊,然後過濾,他們知道如何在ae.Handle(lambda)處理異常,使應用程序停止如果還有一些不可處理的。

+0

我知道你的鏈接提供的例子,並且在處理_這種方式的eception時沒有問題。我的問題是如何處理從continuations拋出的exeptions,而沒有用try catch封裝整個continuation委託,那麼這可能是唯一的方法。我想知道真實世界代碼的最佳實踐,而不是微軟玩具代碼的最佳實踐。乾杯。 – MoonKnight 2012-03-27 10:04:37

+0

爲鏈接+1。非常有用 – SleepyBoBos 2012-08-14 03:08:37

+0

OP想知道如何在不使用Wait的情況下做到這一點。示例全部等待該任務。試試這個[http://msdn.microsoft.com/en-us/library/dd997415.aspx]鏈接。 – 2013-11-04 21:10:00