【发布时间】:2013-03-11 19:35:31
【问题描述】:
为什么我的控制器在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 方法的调用堆栈中的最后一个方法:
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,但同样的情况发生了。
有什么解决办法吗?
【问题讨论】:
-
await 语句后是否保留了对控制器的引用?
-
只有
this本身...它在await之前和之后是同一个对象。 -
它是一样的......但是被丢弃了。
-
是否有另一个线程在对象上调用 dispose?你试过在 dispose 函数上设置断点,看看是谁在调用它吗?
-
已编辑问题以包含 dispose 方法的调用堆栈...调用它的是 MVC。
标签: c# asp.net-mvc-4 .net-4.5 async-await c#-5.0