6

根据文档 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");
}

更新 2void好吧,如果我们更改为某种真实类型, 看起来一切正常,这里:

public async Task<int> Test()
{
    throw new Exception("Hello");
}

因此,看起来像是async void导致服务崩溃的未处理异常,但async Task<SomeType>运行良好,异常过滤器捕获除此之外的所有内容HttpResponseExceptionHttpResponseException并由 Web API 正确处理。

看起来我刚刚自言自语,但是找出为什么无法正确处理动作中的异常会很有趣?async void

4

1 回答 1

5

避免的原因之一async void是这些方法进行错误处理的方式。

async void方法旨在用作事件处理程序。所有其他async方法应该是async Taskor async Task<T>async同步void返回方法的等价物是async Task不是 async void

async返回任务对象的方法会将异常放在该任务对象上。async void方法没有任务对象,因此它们通过在方法开始执行SynchronizationContext时处于活动状态的情况下引发异常来处理异常。async void这模拟了事件处理程序的行为。

于 2013-02-15T05:47:02.020 回答