ASP MVC: When is IController Dispose () called?

I am moving on to a great refactoring / tuning of the speed of one of my larger MVC applications. It was deployed to production for several months, and I began to get timeouts waiting for connections in the connection pool. I tracked the problem to the point that the connections were not configured correctly.

In light of this, I have since made this change to my base controller:

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); } } 

Now I have two questions:

  • Do I imagine a race condition? Since configManager controls a DataContext that provides IQueryable<> parameters for views, I need to make sure Dispose() will not be called on the controller before the view has finished rendering.
  • Is the MVC framework a call to Dispose() on the controller before or after the view is displayed? Or does the MVC structure leave this up to GarbageCollector?
+69
garbage-collection asp.net-mvc idisposable linq-to-sql
Sep 04 '09 at 15:41
source share
2 answers

Dispose is called after the view has been rendered, always .

The view is displayed when ActionResult.ExecuteResult called. This is called (indirectly) on ControllerActionInvoker.InvokeAction , which in turn is called ControllerBase.ExecuteCore .

Since the controller is on the call stack when the view is rendered, it cannot be deleted then.

+59
04 Sep '09 at 15:49
source share

Just to expand Craig Stutz's answer :

ControllerFactory processes when the controller is installed. When implementing the IControllerFactory interface, one of the methods that must be implemented is ReleaseController.

I'm not sure if you use ControllerFactory, regardless of whether you roll your own, but in Reflector looking at DefaultControllerFactory, the ReleaseController method is implemented as follows:

 public virtual void ReleaseController(IController controller) { IDisposable disposable = controller as IDisposable; if (disposable != null) { disposable.Dispose(); } } 

The reference to the IController is passed, if this controller implements IDisposable, then this Dispose method is called. Thus, if you have something that you need to delete after completing the request, that is, after rendering the view. Inherit IDisposable and put your logic in the Dispose method to free up any resources.

The ReleaseController method is called by System.Web.Mvc.MvcHandler, which processes the request and implements IHttpHandler. ProcessRequest passes the HttpContext specified to it and starts the controller search process to process the request by calling into the implemented ControllerFactory. If you look in the ProcessRequest method, you will see a finally block that calls the ControllerFactory ReleaseController. This is only called when the controller returns a ViewResult.

+31
Sep 04 '09 at 16:06
source share



All Articles