2013-02-27 90 views
1

我有一个任务需要在控制器处理请求之后执行,并且响应正在返回客户端。为此,我重写了我的控制器上的OnActionExecuted()事件,并调用此方法中的任务。在asp.net MVC控制器上执行异步OnAction

由于任务可能需要一些时间才能运行,并且返回void,所以我想要异步调用它,以便重写的OnActionExecuted()方法可以立即返回,并且可以在任务执行时将响应发送到客户端。我曾尝试用下面的代码来实现这一点,使用Task.Run()(在.NET 4.5)

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    Task.Run(() => WrapUp()); 
} 

然而,这并不产品预期的效果。当我遍历代码时,它仍然同步执行 - 在OnActionExecuted()方法退出之前调用WrapUp()方法中的所有内容。当WrapUp()方法挂起时,客户端会在收到响应之前等待任务完成。

我需要做什么才能使这项工作按预期进行?

回答

3

OnActionExecuted将立即返回,因为您只在创建和启动任务。你正在观察的行为是不正常的。如果您尝试以下操作,会发生什么情况:

protected override void OnActionExecuted(ActionExecutedContext filterContext) 
{ 
    Task.Run(() => Thread.Sleep(10000)); 
} 

客户端不等待10秒钟才能得到结果,是吗?

+0

是的,你是正确的,客户端不必等待Thread.Sleep()。我观察到的行为非常奇怪,因为每次发出请求时都不一致 - 但在我逐步完成时总会有一定程度的等待时间。我可以看到OnActionExecuted方法退出,但即使在这一点之后,浏览器仍然在等待响应。 – Nick 2013-02-27 12:53:53

+0

详细说明,WrapUp方法实际上调用了控制器上注入依赖项的方法,该方法依次调用更多注入依赖项(我使用StructureMap for IoC)的方法。当我逐步完成调用堆栈的后期阶段时,最终似乎会得到响应。它似乎在等待,直到部分或全部注入的依赖已经从内存中释放出来 - 这可能吗? – Nick 2013-02-27 12:54:25

+0

那么,浏览器在'OnActionExecuted'方法之后应该等待是正常的。这不是执行管道中的最后一种方法。事后还有很多事情要做。诸如寻找,准备和渲染视图本身也需要一些时间。例如'OnResultExecuting','OnResultExecuted'等方法,... – 2013-02-27 12:56:13