4

为什么我的控制器在声明后被处置await

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

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

            return this.View();
    }

我的控制器使用它通过覆盖Dispose方法处理的资源......但使用 async/await 似乎打破了这一点,因为它会在执行 await 语句后立即处理控制器......我怎样才能以异步的方式处理资源支持/等待?

编辑: dispose 方法的调用堆栈中的最后一个方法:

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   

Dispose方法正在被调用disposing = true......这很糟糕。也许是一个错误?

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

有什么解决办法吗?

4

3 回答 3

6

问题中显示的调用堆栈来自 MVC3 而不是 MVC4。不幸的是 MVC3 不支持Task-based 异步调用。当您调用 await 时,任务可能会很好地启动,但 MVC3 对此一无所知,因此它只是调用ToString()它并将其作为ContentResult.

TaskMVC4 中添加了基于 - 的异步支持,实际上甚至不需要从AsyncController. MVC4 中的所有Controllers内容都支持同步和Task基于 - 的异步。AsyncController仅当您使用 Async/Completed 模式时才需要。

于 2013-03-22T05:43:07.387 回答
0

根据堆栈跟踪,似乎无论启动进程请求都决定它结束它,因此您丢失了对控制器的引用,并且它有资格进行垃圾收集/处理。我会调查是什么开始了流程请求以及为什么会结束它。

于 2013-03-22T03:52:02.313 回答
0

我遇到了这个问题,它困扰了我一整天。我终于意识到我在 ControllerFactory 中连接的 ActionInvoker 是从 ControllerActionInvoker 继承的。当我将其更改为 AsyncControllerActionInvoker 时,问题就消失了。

于 2015-05-21T02:32:42.633 回答