2012-12-18 31 views
1

如果我在下面的示例中取消註釋Wait()startNew.Result的行,我將捕獲AggregateException。爲什麼我看不到任何例外,如果這些代碼行被評論?存儲任務內的異常在哪裏?

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      Task<int> startNew = Task.Factory.StartNew(() => int.Parse(""), 
              TaskCreationOptions.LongRunning); 
      //int result = startNew.Result; 
      //startNew.Wait(); 
      Thread.Sleep(10000);    
     } 
     catch (AggregateException ex) 
     { 
      Console.WriteLine("Catched in aggregated"); 
     } 
     catch (Exception) 
     { 
      Console.WriteLine("Catched in general"); 
     } 

     Console.WriteLine("The end"); 
     Console.ReadLine(); 
    } 
} 

回答

0

Jon Skeet是對的,但他的答案並不完整。

我應該補充說,如果您不會調用Wait()或Result,那麼您將面臨在Task對象上調用Finalize方法時的情況,並且該調用將檢查異常內部任務對象集合中是否存在異常然後拋出UnobservedTaskException,導致應用程序立即崩潰(只要您沒有爲TaskScheduler.UnobservedTaskException註冊回調,強烈建議不要)。

2

但爲什麼我看不到任何異常,如果這幾行代碼的註釋?

因爲沒有東西扔他們!你真的不需要想要從一個線程中拋出一個異常,以便在任意點拋出在另一個線程中,而無需執行任何操作。

Task<>記得例外,但它不會扔他們,除非你明確執行操作如Wait()Result,如您所見。

您還可以使用Task.Exception檢查錯誤。

+0

所以我正確的是ThreadPool.QueueUserWorkItem()立即拋出異常,因爲沒有機制來獲得結果或等待完成? – EngineerSpock