ASP MVC:什么时候IController Dispose()被调用?
我正在经历一个大的MVC应用程序的重构/速度调整。 它已经被部署到生产了几个月了,我开始在连接池中等待连接。 我跟踪了这个问题,直到没有妥善处理的连接。
有鉴于此,我已经把这个变化交给了我的基础控制者:
public class MyBaseController : Controller { private ConfigurationManager configManager; // Manages the data context. public MyBaseController() { configManager = new ConfigurationManager(); } protected override void Dispose(bool disposing) { if (disposing) { if (this.configManager != null) { this.configManager.Dispose(); this.configManager = null; } } base.Dispose(disposing); } }
现在我有两个问题:
- 我介绍一个竞赛条件? 由于
configManager
pipe理将IQueryable<>
参数公开给视图的DataContext
,所以我需要确保在视图完成呈现之前不会在控制器上调用Dispose()
。 - 视图呈现之前或之后,MVC框架是否在Controller上调用
Dispose()
? 或者,MVC框架是否将其留给GarbageCollector?
总是在渲染视图之后调用Dispose。
该视图在对ActionResult.ExecuteResult
的调用中呈现。 这由ControllerActionInvoker.InvokeAction
(间接)调用, ControllerBase.ExecuteCore
又由ControllerBase.ExecuteCore
调用。
由于控制器在渲染视图时处于调用堆栈中,因此无法处理。
只是为了扩大克雷格Stuntz的答案 :
ControllerFactory在处理Controller时处理。 在实现IControllerFactory接口时,需要实现的方法之一是ReleaseController。
我不确定你正在使用什么ControllerFactory,不pipe你是自己制作的,而是在Reflector中查看DefaultControllerFactory,ReleaseController方法是这样实现的:
public virtual void ReleaseController(IController controller) { IDisposable disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); } }
如果控制器实现了IDisposable,则传入IController引用,然后调用Dispose方法。 所以,如果你有什么需要处理的请求完成后,这是视图渲染后。 inheritanceIDisposable并将您的逻辑放在Dispose方法中释放任何资源。
ReleaseController方法由处理请求的System.Web.Mvc.MvcHandler调用,它实现IHttpHandler。 ProcessRequest接受HttpContext给它,并通过调用实现的ControllerFactory来启动find控制器来处理请求的过程。 如果您查看ProcessRequest方法,您将看到调用ControllerFactory的ReleaseController的finally块。 这只在Controller返回ViewResult时调用。