2009-09-04 88 views
71

我要通過我的大MVC應用程序中的一個大的重構/速度調整。它已被部署到生產幾個月,現在我開始在連接池中等待連接。我已經跟蹤了這個問題,直到沒有妥善處理的連接問題。ASP MVC:何時調用IController Dispose()?

在的光,因爲我已經做出這個改變我的基本控制器:

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

現在,我有兩個問題:

  1. 我是否引入競爭條件?由於configManager管理暴露IQueryable<>參數 的意見DataContext,我需要確保Dispose()不會在控制器上被稱爲 視圖渲染完畢之前。
  2. 是否控制器上的MVC框架調用Dispose()之前或視圖渲染後?或者,MVC框架是否將 保留到GarbageCollector?
+1

我SOOO lookig着這個問題的答案之一!偉大的問題! – 2009-09-04 15:43:43

+0

沒有看其他代碼(你的或ASP.NET MVC的..)爲什麼你需要清空configManager?這有幫助嗎?在你們任何一個之前徹底思考「DUH」我.. – 2010-10-11 14:54:31

+0

我的意思是在一般情況下,比賽條件可以很容易地被刪除。在這種特殊情況下,我懷疑一個控制器實例會被多個線程使用,因此不存在任何競爭條件的風險。 – 2010-10-11 14:56:25

回答

60

視圖渲染之後調用Dispose,總是

該視圖在調用ActionResult.ExecuteResult呈現。這被稱爲(間接)ControllerActionInvoker.InvokeAction,而這又被ControllerBase.ExecuteCore調用。

由於控制器是在調用棧時,視圖被呈現,它不能被設置然後。

+0

太棒了,你有文件嗎?我只是想確定。 – 2009-09-04 15:49:53

+0

文檔是MVC源代碼。看到擴展的答案。 – 2009-09-04 15:57:00

+0

完美。謝謝! – 2009-09-04 16:02:48

32

只是爲了擴大Craig Stuntz's Answer

當控制器被設置在的ControllerFactory處理。在實現IControllerFactory接口時,需要實現的方法之一是ReleaseController。

我不知道是什麼的ControllerFactory您使用,無論你滾你自己的,但在反射看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時調用。

+0

真棒回答。我無法弄清楚爲什麼Controller對象的直接實例不讓我調用Dispose(),但看起來我需要使用IDisposable接口創建它的新實例。這對我有用! – 2012-09-12 21:30:44

+0

那麼......'HttpContext'是男性?現在我真的很困惑。 – 2016-02-14 20:17:26