异步异常不被抓住或者被吞噬 [英] Async exception not being caught or being swallowed

查看:227
本文介绍了异步异常不被抓住或者被吞噬的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建的只是运行其他异步方法有点令人费解的异步方法。您可以忽略大部分因为只有行VAR mSpekTask ......很感兴趣,另外,我不在乎逻辑,我只是​​想知道我的异常去了。我的主要问题是,ex.ToString()永远​​不会打,即使里面mSpecTask异常definitly发生。

 公共异步任务LoadAsync(IEnumerable的< ProductRequest>饲料,INT客户ID,
      IProgress< INT> mSpecProgress,动作<任务> mSpecCompletionHandler)
  {
        变种的id = feed.Select(X => x.ProductId.ToString())。鲜明()了ToList();        尝试
        {
           VAR mSpecTask = this.LoadMSpecAsync(mSpecProgress,IDS);
        }
        赶上(异常前)
        {
           ex.ToString();
        }
  }

下面是code为LoadMSpecAsync

 公共任务< ResultSet中> LoadMSpecAsync(IProgress< INT> PRG,
     IEnumerable的<串GT; IDS)
  {
     返回this.LoadAsync(PRG,IDS,Selector.M,SPMS,X => x.Order);
  }

下面是code代表LoadAsync,等待db.ExecuteTVP(进步,spName,IDS,参数)产生异常。

 专用异步任务<&字典LT;配对,动态>> LoadAsync(IProgress< INT>的进步,
     IEnumerable的<串GT; IDS,选择S,串spName,Func键<动态,诠释> K,
      FUNC<动态,动态> F = NULL,对象参数= NULL)
  {
     。参数=新ExpandoObject()CopyFromSafe(参数);
     如果(spName = SPMAP!)((动态)参数).lang = this.language code;     使用(VAR DB =新的SqlConnection(this.connectionString))
     {
        等待db.OpenAsync();        VAR的结果=等待db.ExecuteTVP(进步,spName,IDS,参数);        db.Close();
     }     返回this.data [S]。
  }


解决方案

在一个异步方法抛出一个异常,该异常被放置在返回任务。它不直接升高到调用者。这是由设计。

所以,你必须为等待工作从返回 LoadMSpecAsync 或你的 mSpecCompletionHandler 检查异常的工作参数。它会显示在那里。

I created a somewhat convoluted async method that just runs other async methods. You can disregard most of it as only the line var mSpekTask... is of interest, also, I don't care about the logic, I only want to know where my exception went. My main problem is that ex.ToString() is never hit even though inside mSpecTask an exception definitly happens.

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();
        }
  }

Here is the code for LoadMSpecAsync

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

Here is the code for LoadAsync, await db.ExecuteTVP(progress, spName, ids, parameters) generates an exception.

      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];
  }

解决方案

When an async method throws an exception, that exception is placed on the returned Task. It's not raised directly to the caller. This is by design.

So, you have to either await the Task returned from LoadMSpecAsync or have your mSpecCompletionHandler examine its Task argument for exceptions. It will show up there.

这篇关于异步异常不被抓住或者被吞噬的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆