2012-09-18 85 views
5

當處理在TPL任務異常我所遇到的兩種方式來處理異常。第一個捕獲異常的任務中,結果像這樣內返回它:任務並行庫異常處理

var task = Task<Exception>.Factory.StartNew(
    () => 
     { 
      try 
      { 
       // Do Something 

       return null; 
      } 
      catch (System.Exception e) 
      { 
       return e; 
      } 
     }); 

task.ContinueWith(
    r => 
     { 
      if (r.Result != null) 
      { 
       // Handle Exception 
      } 
     }); 

二是文檔中顯示的一個,我想用正確的方法做的事情:

var task = Task.Factory.StartNew(
    () => 
     { 
      // Do Something 
     }); 
task.ContinueWith(
    r => 
     { 
      if (r.Exception != null) 
      { 
       // Handle Aggregate Exception 
       r.Exception.Handle(y => true); 
      } 
     }); 

我想知道第一種方法是否有什麼問題? 我已經收到'未處理的聚合異常'例外,每次都使用這種技術,並想知道如何發生這種情況?

爲了澄清,我認爲第二種模式是更好的,但我有一塊代碼,它使用第一種模式,我試圖找出它是否需要重新分解,即如果事實證明不是所有的例外都會被困住。

+0

我有同樣的問題,雖然我與task.IsFaulted檢查,我發現,如果它有任務過程中的異常,即使我做的第一件事就是檢查是什麼,以及它指出,放棄,但仍引起的問題..我有一個例外泄漏,不應該有.. – BugFinder

回答

3

第一種方法假設異常將提高爲每次調用。雖然這可能是事實,但例外情況似乎不是「特殊」的,並且是一個設計問題的氣味。如果例外情況並不例外,那麼結果沒有多大意義。另一個問題是,如果你想有一個「結果」(比Exception其他即東西),你不能因爲一個只有Result插槽用於一個Exception。另一個問題是,你不會在主線程上重新拋出異常(你可以手動執行),所以你不會得到catch語義(即你使用的是Handle方法)。

第二種方法將被更多的人更好地理解。

+0

感謝您的意見。我在預計會出現異常(數據庫訪問)的存儲庫中使用此方法。如果我需要返回的結果,我有一個RepositoryResult類,它可以由任務返回幷包含結果和異常。任務延續是發生異常處理的地方(即調用異常處理服務)。我真正想知道的是,如何以第一種方法結束未處理的聚合異常? – user1680766

+0

所以,你會遇到不一致的處理異常的方法。這並不是說'Task'與任務''一致的方式,由於缺乏一個結果性質的,但已經有一個'Task.Exception'財產以及'IsFaulted' ... –

+0

我同意,第二種方法是更好的一個。不幸的是,我採用了一些代碼,它大量使用了第一種模式,現在我需要決定是否有必要返回並重新計算它 - 因此,第一種模式是否會導致未處理的聚合異常。 – user1680766