根据documentation HttpResponseException
自动由Web API处理,而Web API应该将HttpResponseMessage
返回给具有相应HttpStatusCode
的客户端。它通常有用......
但是,如果我们从标有HttpResponseException
的操作中抛出async
,那么这只是不起作用而HttpResponseException
只会崩溃整个服务,例如“用户未处理异常代码“消息。添加自定义异常过滤器无法解决问题,因为Web API无法捕获HttpResponseException
消息。
更新1
我进一步调查并发现,只要将await
修饰符添加到操作中,此操作中的每个未处理的异常都会导致Web API服务崩溃。并且不涉及ExceptionFilterAttributes,Web API只是不执行它们。您甚至不必从异步代码中抛出异常,只需将async
添加到操作中就可以使每个异常完全无法处理。
这里可以正常工作,异常过滤器可以捕获异常:
public void Test()
{
throw new Exception("Hello");
}
这会导致服务崩溃:
public async void Test()
{
throw new Exception("Hello");
}
更新2
好吧,如果我们将void
改为某种真实类型,看起来一切正常:
public async Task<int> Test()
{
throw new Exception("Hello");
}
因此,看起来async void
中的未处理异常导致服务崩溃,但async Task<SomeType>
运行良好,异常过滤器会捕获除HttpResponseException
以外的所有内容,并且HttpResponseException
由Web正确处理API。
看起来我刚才和自己说过话,但是找出为什么async void
行动中的例外无法正确处理会很有意思?
答案 0 :(得分:4)
避免async void
的原因之一是这些方法进行错误处理的方式。
async void
方法旨在用作事件处理程序。 所有其他async
方法应为async Task
或async Task<T>
。 async
等效的同步void
- 返回方法为async Task
,不 async void
。
async
方法会将异常放在该任务对象上。 async void
方法没有任务对象,因此它们通过在SynchronizationContext
方法开始执行时处于活动状态的async void
上提升异常来处理异常。这模拟了事件处理程序的行为。