哪里如果不是等待一个异步任务抛出异常? [英] Where does an async Task throw Exception if it is not awaited?
问题描述
我有下面的例子:(也请阅读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 theMyAsyncMethod
and ifPostAsync
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 aTask
will put all of its exceptions on that returnedTask
.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 returnedTask
).Is it possible to use ContinueWith to handle exceptions in the current class?
Yes, but
await
is cleaner.这篇关于哪里如果不是等待一个异步任务抛出异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!