哪里如果不是等待一个异步任务抛出异常? [英] Where does an async Task throw Exception if it is not awaited?

查看:126
本文介绍了哪里如果不是等待一个异步任务抛出异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有下面的例子:(也请阅读code的意见,因为它会更有意义)

 公共异步任务<任务<结果>> MyAsyncMethod()
{
    任务<结果> resultTask =等待_mySender.PostAsync();
    返回resultTask;    //在现实生活中的案例这将返回到一个不同的组件,我不能改变
   //但我需要做的在这里的一些结果异常处理
}

让我们假设_的 PostAsync 方法 mySender 是这样的:

 公共任务<任务<结果>> PostAsync()
{
  任务<结果>结果= GetSomeTask();
  返回结果;
}

现在的问题是:

由于我不期待实际结果 MyAsyncMethod ,如果 PostAsync 方法抛出一个异常,其中上下文是异常将被引发和处理?

有什么办法,我可以处理我的装配异常?

我很惊讶,当我试图改变 MyAsyncMethod 来:

 公共异步任务<任务<结果>> MyAsyncMethod()
{
  尝试
  {
    任务<结果> resultTask =等待_mySender.PostAsync();
    返回resultTask;
  }
  赶上(MyCustomException前)
  {
  }
}

异常被抓到这里来,事件是否有实际的结果没有游览车。它发生 PostAsync 的结果已经可以和异常是在这种情况下正确抛出?

时有可能使用 ContinueWith 来处理当前类的异常?例如:

 公共异步任务<任务<结果>> MyAsyncMethod()
{
    任务<结果> resultTask =等待_mySender.PostAsync();
    VAR exceptionHandlingTask = resultTask.ContinueWith(T => {手柄(t.Exception)},TaskContinuationOptions.OnlyOnFaulted);
    返回resultTask;
}


解决方案

这是一个很大的问题,打包成一个问题,但OK ......


  

哪里异步任务抛出异常,如果它不期待?


不可观测任务异常由 TaskScheduler.UnobservedTaskException 引发的事件。引发此事件终于,是因为任务必须实际垃圾收集被认为是其异常之前未处理。


  

由于我不期待在MyAsyncMethod和实际结果,如果PostAsync方法抛出一个异常,其中上下文是异常将被引发和处理?


这是使用异步修改并返回一个工作会把所有的异常上返回<任何方法code>工作。


  

有什么办法,我可以在我的组装处理异常?


是的,你可以取代返回的任务,是这样的:

 异步任务&LT;结果&GT; HandleExceptionsAsync(任务&LT;结果&GT;原)
{
  尝试
  {
    返回等待原件;
  }
  赶...
}公共异步任务&LT;任务&LT;结果&GT;&GT; MyAsyncMethod()
{
  任务&LT;结果&GT; resultTask =等待_mySender.PostAsync();
  返回HandleExceptionsAsync(resultTask);
}


  

我很惊讶,当我试图改变MyAsyncMethod为[同步返回内部任务]异常被抓到这里来,即使有实际结果没有​​游览车。


这实际上意味着,我们在调用该方法不是异步任务,作为你的code示例所示。这是一个非 - 异步工作 -returning方法,当这些方法之一抛出异常,它只是治疗像任何其他异常(即,它直接传递到调用堆栈,它不是放在返回工作


  

是否有可能使用ContinueWith在当前的类来处理异常?


是的,但等待是清洁的。

I have the following example: (please also read comments in code, as it will make more sense )

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
}

let's assume the PostAsync method of _mySender looks like this:

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

The question is:

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?

and

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

I was surprised that when I tried to change MyAsyncMethod to:

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

the exception was caught here, event if there's no await for the actual result. It happens that the result of PostAsync is already available and the exception is thrown in this context right??

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

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

解决方案

This is a lot of questions to pack into a single "question", but OK...

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

Unobserved Task exceptions are raised by the TaskScheduler.UnobservedTaskException event. This event is raised "eventually" because the Task must actually be garbage collected before its exception is considered unhandled.

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?

Any method that uses the async modifier and returns a Task will put all of its exceptions on that returned Task.

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

Yes, you could replace the returned task, something like:

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.

That actually means that the method you're calling is not async Task, as your code example shows. It's a non-async, Task-returning method, and when one of those methods throws an exception, it's treated just like any other exception (i.e., it passes directly up the call stack; it's not placed on the returned Task).

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

Yes, but await is cleaner.

这篇关于哪里如果不是等待一个异步任务抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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