2013-03-04 42 views
1

更新: TL; DR趕上你要awaitTask.WaitAll,或.Result異步方法表達式。異步異常捕獲或者被吞噬從未來

我創建了一個稍微複雜的異步方法,只是運行其他異步方法。你可以忽略它的大部分,因爲只有var mSpekTask這一行是有意義的,我也不關心邏輯,我只想知道我的異常去了哪裏。我的主要問題是ex.ToString()從來沒有命中,即使mSpecTask內部發生了異常。

public async Task LoadAsync(IEnumerable<ProductRequest> feed, int? customerId, 
     IProgress<int> mSpecProgress, Action<Task> mSpecCompletionHandler) 
    { 
     var ids = feed.Select(x => x.ProductId.ToString()).Distinct().ToList(); 

     try 
     { 
      var mSpecTask = this.LoadMSpecAsync(mSpecProgress, ids); 
     } 
     catch (Exception ex) 
     { 
      ex.ToString(); 
     } 
    } 

這裏是LoadMSpecAsync

public Task<ResultSet> LoadMSpecAsync(IProgress<int> prg, 
    IEnumerable<string> ids) 
    { 
    return this.LoadAsync(prg, ids, Selector.M, SPMS, x => x.Order); 
    } 

代碼在這裏是用於LoadAsync代碼,等待db.ExecuteTVP(進展,spName,IDS,參數)生成異常。

 private async Task<Dictionary<Pair, dynamic>> LoadAsync(IProgress<int> progress, 
    IEnumerable<string> ids, Selector s, string spName, Func<dynamic, int> k, 
     Func<dynamic, dynamic> f = null, object parameters = null) 
    { 
    parameters = new ExpandoObject().CopyFromSafe(parameters); 
    if (spName != SPMAP) ((dynamic)parameters).lang = this.languageCode; 

    using (var db = new SqlConnection(this.connectionString)) 
    { 
     await db.OpenAsync(); 

     var results = await db.ExecuteTVP(progress, spName, ids, parameters); 

     db.Close(); 
    } 

    return this.data[s]; 
    } 
+5

如果我們可以忽略它的大部分,爲什麼你把它放在首位?請僅張貼相關部分。更好:創造一個簡短,乾淨的複製品。 – 2013-03-04 13:41:01

回答

7

async方法拋出一個異常,該異常被放置在返回Task。它不是直接向調用者提出的。這是設計。

所以,你必須要麼awaitTaskLoadMSpecAsync返回或有你mSpecCompletionHandler檢查其Task參數例外。它會出現在那裏。

1

您可以處理未觀測到的任務異常如下:

TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs eventArgs) => 
{ 
     eventArgs.SetObserved(); 
     ((AggregateException)eventArgs.Exception).Handle(ex => 
     { 
      //TODO: inspect type and handle exception 
      return true; 
     }); 
}; 
+0

有趣,我不知道這是可能的 – 2013-03-05 08:52:35

0

我打算爲自己的問題添加一個答案,因爲我找到了一條有用的信息。中間方法LoadMSpecAsync吞吐異常。爲了不發生這需要一個小柚木。您需要在返回類型之前添加async關鍵字,並在「返回」之後添加「await」關鍵字。