我正在对我的一个较大的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
管理了DataContext
公开IQueryable<>
参数的Dispose()
观点,我需要确保不会调用Dispose()
在视图完成渲染之前在控制器上。答案 0 :(得分:67)
在渲染视图后调用Dispose,始终。
视图在ActionResult.ExecuteResult
的调用中呈现。这是ControllerActionInvoker.InvokeAction
(间接)调用的,ControllerBase.ExecuteCore
又调用了{{1}}。
由于在渲染视图时控制器位于调用堆栈中,因此无法处理它。
答案 1 :(得分:36)
ControllerFactory处理Controller的处理时间。在实现IControllerFactory接口时,需要实现的方法之一是ReleaseController。
我不确定您使用的是什么ControllerFactory,无论您是自己编写的,还是在Reflector中查看DefaultControllerFactory,ReleaseController方法都是这样实现的:
public virtual void ReleaseController(IController controller)
{
IDisposable disposable = controller as IDisposable;
if (disposable != null)
{
disposable.Dispose();
}
}
传入IController引用,如果该控制器实现IDisposable,则调用控制器Dispose方法。因此,如果您在请求完成后需要处理任何内容,那么在呈现视图之后。继承IDisposable并将您的逻辑放在Dispose方法中以释放任何资源。
ReleaseController方法由System.Web.Mvc.MvcHandler调用,它处理请求并实现IHttpHandler。 ProcessRequest获取给它的HttpContext,并通过调用实现的ControllerFactory开始寻找控制器来处理请求的过程。如果查看ProcessRequest方法,您将看到调用ControllerFactory的ReleaseController的finally块。仅在Controller返回ViewResult时调用此方法。