我正在对我的一个较大的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);
}
}
现在,我有两个问题:
DataContext
管理着向视图公开IQueryable<>
参数的控制器,所以我需要确保在视图完成之前不会在控制器上调用Dispose()
。在呈现视图之前或之后,MVC框架在控制器上调用?或者,MVC框架是否将其留给了GarbageCollector??
发布于 2009-09-04 15:49:03
Dispose在视图呈现后调用,始终为。
视图在对ActionResult.ExecuteResult
的调用中呈现。这是由ControllerActionInvoker.InvokeAction
(间接地)调用的,而ControllerBase.ExecuteCore
又调用它。
因为在呈现视图时控制器在调用堆栈中,所以不能在那时将其释放。
发布于 2009-09-04 16:06:46
只是为了扩展一下Craig Stuntz's Answer
当控制器被释放时,ControllerFactory会进行处理。在实现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块。仅当控制器返回ViewResult时才会调用此方法。
https://stackoverflow.com/questions/1380019
复制相似问题