2012-11-07 45 views
5

我基本上想知道如何在C#中通過await關鍵字等待來自異步方法的異常。例如考慮下面的小控制檯程序,其中最重要的是包含一個名爲AwaitSync的方法。 AwaitSync調用TestAsync,它返回執行時引發異常的任務。我試圖在AwaitAsync,中發現異常,但未處理如何在C#中捕獲正在等待的異步方法的異常?

class Program 
{ 
    static void Main(string[] args) 
    { 
     AwaitAsync(); 
     Console.ReadKey(); 
    } 

    static async Task AwaitAsync() 
    { 
     try 
     { 
      await TestAsync(); 
     } 
     catch (Exception) 
     { 
      Console.WriteLine("Exception caught"); 
     } 
    } 

    static Task TestAsync() 
    { 
     return Task.Factory.StartNew(() => { throw new Exception("Test"); }); 
    } 
} 

我怎麼去捕左右從TestAsync返回的任務異常?雖然這個例子是一個控制檯程序,但我的現實生活問題在ASP.NET MVC/Web API的上下文中。

編輯: 原來的異常被抓到,由於技術原因,我只是在終端關閉之前沒有注意到的「捕獲異常」消息。無論如何,Jon Skeet的回答對我對await和異常處理的理解非常有價值。

+1

你是說這不起作用? – jishi

+2

當我運行你的代碼時,我看到「Exception caught」。 – spender

+0

它不會被抓住。我會再檢查一次。 – aknuds1

回答

10

await表達將調用與由TestAsync返回的Task相關聯的TaskAwaiterGetResult()生成的代碼。

GetResult會發現,任務發生故障,取從任務中的AggregateException第一異常,並拋出。最終的結果是你的catch塊會捕獲你的任務中拋出的異常 - 但是如果你等待一個有多個異常的任務,除非你採取特殊的行動,否則你只能看到第一個。對此的各種方法)。

當你聲稱異常實際上得不到處理,似乎有什麼東西比你展示什麼其他的代碼 - 爲代碼你給了當然應該工作,確實對我來說。

+0

謝謝,午餐後會詳細說明。 – aknuds1

+0

原來的異常其實抓住了,但確認消息不被寫入到控制檯之前,我按一鍵結束程序。因此,我沒有注意到第一次印刷的信息。猜不同步需要一些時間來適應:) – aknuds1

+0

非常感謝BTW您的例外是如何用的await,我的理解是非常有用的處理說明。 – aknuds1