c# – 如果没有等待,异步任务会抛出异常吗?

栏目: ASP.NET · 发布时间: 5年前

内容简介:翻译自:https://stackoverflow.com/questions/25691114/where-does-an-async-task-throw-exception-if-it-is-not-awaited

我有以下示例:(请同时阅读代码中的注释,因为它会更有意义)

public async Task<Task<Result>> MyAsyncMethod() 
{
    Task<Result> resultTask = await _mySender.PostAsync();
    return resultTask; 

    // in real-life case this returns to a different assembly which I can't change
   // but I need to do some exception handling on the Result in here
}

让我们假设_mySender的PostAsync方法如下所示:

public Task<Task<Result>> PostAsync() 
{
  Task<Result> result = GetSomeTask(); 
  return result;
}

问题是:

因为我没有等待MyAsyncMethod中的实际结果,并且如果PostAsync方法抛出异常,在哪个上下文中会抛出并处理异常?

有什么办法可以处理我的程序集中的异常吗?

当我尝试将MyAsyncMethod更改为:时,我感到很惊讶:

public async Task<Task<Result>> MyAsyncMethod() 
{
  try 
  {
    Task<Result> resultTask = await _mySender.PostAsync();
    return resultTask; 
  }
  catch (MyCustomException ex) 
  {
  } 
}

如果没有等待实际结果,则在此处捕获异常.碰巧PostAsync的结果已经可用,并且在这个上下文中抛出了异常吗?

是否可以使用ContinueWith来处理当前类中的异常?例如:

public async Task<Task<Result>> MyAsyncMethod() 
{
    Task<Result> resultTask = await _mySender.PostAsync();
    var exceptionHandlingTask = resultTask.ContinueWith(t => { handle(t.Exception)}, TaskContinuationOptions.OnlyOnFaulted);
    return resultTask;
}

这可以包含在一个单一的“问题”中,但是好的……

Where does an async Task throw Exception if it is not awaited?

TaskScheduler.UnobservedTaskException事件引发了未观察到的任务异常.此事件“最终”被引发,因为在将异常视为未处理之前,该实际上必须进行垃圾回收.

As I don’t await for the actual Result in the MyAsyncMethod and if PostAsync method throws an exception, in which context is the exception going to be thrown and handled?

任何使用async修饰符并返回Task的方法都会将所有异常放在返回的Task上.

Is there any way I can handle exceptions in my assembly?

是的,您可以替换返回的任务,例如:

async Task<Result> HandleExceptionsAsync(Task<Result> original)
{
  try
  {
    return await original;
  }
  catch ...
}

public async Task<Task<Result>> MyAsyncMethod()
{
  Task<Result> resultTask = await _mySender.PostAsync();
  return HandleExceptionsAsync(resultTask);
}
I was surprised that when I tried to change MyAsyncMethod to [synchronously return the inner task] the exception was caught here, even if there’s no await for the actual result.

这实际上意味着您调用的方法不是异步任务,正如您的代码示例所示.它是一个非异步的,任务返回方法,当其中一个方法抛出异常时,它就像任何其他异常一样被处理(即,它直接传递给调用堆栈;它不会放在返回的Task上).

Is it possible to use ContinueWith to handle exceptions in the current class?

是的,但等待更清洁.

翻译自:https://stackoverflow.com/questions/25691114/where-does-an-async-task-throw-exception-if-it-is-not-awaited


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

算法心得:高效算法的奥秘(原书第2版)

算法心得:高效算法的奥秘(原书第2版)

(美)Henry S. Warren, Jr. / 爱飞翔 / 机械工业出版社 / 2014-3 / 89.00

【编辑推荐】 由在IBM工作50余年的资深计算机专家撰写,Amazon全五星评价,算法领域最有影响力的著作之一 Google公司首席架构师、Jolt大奖得主Hoshua Bloch和Emacs合作创始人、C语言畅销书作者Guy Steele倾情推荐 算法的艺术和数学的智慧在本书中得到了完美体现,书中总结了大量高效、优雅和奇妙的算法,并从数学角度剖析了其背后的原理 【读者评价......一起来看看 《算法心得:高效算法的奥秘(原书第2版)》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具