我理解等待等待完成任务(等待)。 但我对这实际意味着什么感到困惑。
不的代码:
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堆栈执行其他工作并在await asyncOperation()操作完成后返回。
我也在其他地方使用等待 - (例如等待Web服务响应) - 我没有在任何地方遇到过类似的问题。我想知道为什么IActionFilterAttribute的行为不同。实际上,我的Web服务调用可能比将响应内容读入字符串要长。
有人可以赐教吗?我觉得我不理解这个概念。答案 0 :(得分:6)
将异步代码添加到返回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;
}
}
答案 1 :(得分:1)
而不是实施
public async override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
您必须按如下方式实现OnActionExecuted
方法的异步版本:
public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
这样你可以在方法中使用await,行为就像你期望的那样。
希望这有帮助。