异步WebApi ActionFilterAttribute。异步模块或处理程序,而异步操作仍然悬而未决
问题描述:
完成我明白等待的任务(一个awaitable)完成等待。 但我对这实际上意味着什么感到困惑。异步WebApi ActionFilterAttribute。异步模块或处理程序,而异步操作仍然悬而未决
该不工作的代码:
public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response.Content != null)
{
var responseContent = await actionExecutedContext.Response.Content.ReadAsStringAsync();
DoSomething(responseContent);
}
}
的代码确实工作:
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext.Response.Content != null)
{
var responseContent = actionExecutedContext.Response.Content.ReadAsStringAsync().ContinueWith(
task =>
{
DoSomething(task.Result);
});
}
}
显然错误消息异步模块或处理程序完成,而异步操作仍在进行中。告诉我,没有等待异步调用完成,而是继续“主”线程。我期望线程继续,但不在当前的方法。我认为线程将返回到asp.net堆栈做一些其他的工作,并返回一次等待asyncOperation()操作完成。
我使用的是等待在其他地方太 - (例如等待Web服务响应) - 我没有碰到类似问题的任何地方。我想知道为什么IActionFilterAttribute行为有所不同。事实上,我的Web服务调用可能比读取字符串中的响应内容更长。
有人请赐教吗?我有这种感觉,我不理解这个概念。
答
添加异步代码返回void是危险的,几乎从来没有你真正想做的事情的方法。请参阅What's the difference between returning void and returning a Task?。
相反,您需要重写/实现返回任务的方法。在这种情况下,ActionFilterAttribute隐藏了IHttpActionFilter提供的任务,因此您需要实现IActionFilter(ExecuteActionFilterAsync)。如果你想使用你的代码作为属性,只要确保你也从Attribute类派生。
例如:
public class AsyncActionFilterAttribute : Attribute, IActionFilter
{
public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
{
HttpResponseMessage response = await continuation();
DoSomething(response);
return response;
}
}
答
,而不是实施
public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
你必须实现OnActionExecuted
方法的异步版本如下:
public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
这样,您就可以使用等待内部的方法和行为将如你所料。
希望这会有所帮助。
动作过滤器(MVC的一部分,而不是WebAPI)不支持异步操作。如果您需要异步操作筛选器,请尝试使用消息处理程序。哦,并[在这里投票](http://aspnet.codeplex.com/workitem/9582)。 – 2013-03-19 15:19:25
这是一个WebAPI问题,我使用正确的ActionFilterAttribute(System.Web.Http ...) - 你是说它应该工作? :) – lapsus 2013-03-19 15:32:16
我明白了。在这种情况下,您可能需要定义自己的'AsyncActionFilterAttribute'并实现'IActionFilter.ExecuteActionFilterAsync'。 – 2013-03-19 15:37:12