c# – 为什么MVC 4在行动等待时会丢弃控制器?

为什么我的控制器在await语句之后被处理?

    public async Task<ViewResult> MyAction()
    {
            await Task.Yield();

            // controller disposed at this point... why?

            return this.View();
    }

我的控制器通过重写Dispose方法来使用它所处理的资源……但是使用async / await似乎打破了这一点,因为它在执行await语句后立即处理控制器…我如何以一种方式处理资源是否支持async / await?

编辑:dispose方法的callstack中的最后一个方法:

MyWebRole.dll!MyWebRole.Code.MyController.Dispose(bool disposing = true) Line 102   C#
System.Web.Mvc.dll!System.Web.Mvc.Controller.Dispose() + 0x25 bytes   
System.Web.Mvc.dll!System.Web.Mvc.DefaultControllerFactory.ReleaseController(System.Web.Mvc.IController controller = {MyWebRole.Areas.App.Controllers.LongPollingController}) + 0x3e bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.BeginProcessRequest.AnonymousMethod__5() + 0x70 bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.MakeVoidDelegate.AnonymousMethod__0() + 0x2d bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.BeginSynchronous<System.Web.Mvc.Async.AsyncVoid>.AnonymousMethod__7(System.IAsyncResult _ = {System.Web.Mvc.Async.SimpleAsyncResult}) + 0x2b bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>.End() + 0x99 bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.End<System.Web.Mvc.Async.AsyncVoid>(System.IAsyncResult asyncResult = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}, object tag = {object}) + 0x3c bytes   
System.Web.Mvc.dll!System.Web.Mvc.Async.AsyncResultWrapper.End(System.IAsyncResult asyncResult = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}, object tag = {object}) + 0x29 bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.EndProcessRequest.AnonymousMethod__d() + 0x27 bytes   
System.Web.Mvc.dll!System.Web.Mvc.SecurityUtil.GetCallInAppTrustThunk.AnonymousMethod__0(System.Action f = {Method = {System.Reflection.RuntimeMethodInfo}}) + 0x20 bytes   
System.Web.Mvc.dll!System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(System.Action action = {Method = {System.Reflection.RuntimeMethodInfo}}) + 0x3e bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.EndProcessRequest(System.IAsyncResult asyncResult = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}) + 0x77 bytes   
System.Web.Mvc.dll!System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(System.IAsyncResult result = {System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult<System.Web.Mvc.Async.AsyncVoid>}) + 0x27 bytes   

使用disposing = true来调用Dispose方法……这很糟糕.也许是个bug?

编辑2:我尝试了子类化AsyncController,但同样的情况发生.

有什么工作吗?

最佳答案
问题中显示的调用堆栈来自MVC3而不是MVC4.不幸的是,MVC3不支持基于任务的异步调用.当你调用await时,很可能启动任务,但是MVC3对此一无所知,所以它只调用它上面的ToString()并将其作为ContentResult返回.

在MVC4中添加了基于任务的异步支持,实际上甚至不需要从AsyncController派生. MVC4中的所有控制器都支持同步和基于任务的异步.如果使用Async / Completed模式,则只需要AsyncController.

转载注明原文:c# – 为什么MVC 4在行动等待时会丢弃控制器? - 代码日志