2013-03-04 43 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”关键字。