0

未来更新: 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的代码,await db.ExecuteTVP(progress, spName, ids, parameters) 产生异常。

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

4 回答 4

9

async方法抛出异常时,该异常被放置在返回的Task. 它不会直接向调用者提出。这是设计使然。

因此,您必须返回 from或检查其await异常参数。它会出现在那里。TaskLoadMSpecAsyncmSpecCompletionHandlerTask

于 2013-03-04T14:00:44.807 回答
1

您可以按如下方式处理未观察到的任务异常:

TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs eventArgs) =>
{
      eventArgs.SetObserved();
      ((AggregateException)eventArgs.Exception).Handle(ex =>
      {
          //TODO: inspect type and handle exception
          return true;
      });
};
于 2013-03-04T13:40:55.663 回答
0

我将为我自己的问题添加一个答案,因为我发现了一条有用的信息。中间方法 LoadMSpecAsync 正在处理异常。为了避免这种情况发生,它需要一点柚木。您需要在返回类型之前添加 async 关键字,在“return”之后添加“await”关键字。

于 2013-03-05T08:54:39.447 回答
-2

我有一个异常被myTask.Wait()(或 WaitAsync)吞没,但这是一个任务嵌套问题。也就是说,当我执行myTask.Wait()时,myTask有一个传入的参数 Task,它也称为myParameterTask.Wait()参数任务有自己的Exception -catch 并且没有throw,所以最初抛出的 Exception 没有传播回调用线程。

我认为myTask.Wait()抛出异常存在问题,但事实并非如此。

于 2021-12-03T20:12:11.387 回答