2010-11-15 61 views
4

我在ASP.NET MVC項目中已經有很多連接池超時了。我一直在閱讀,即使Linq-to-SQL應該爲我處置它並不總是工作,也不是手動處理任何繼承IDisposable是不好的做法。我正確使用DataContext.Dispose()嗎?

我正在使用所有我的Linq-to-SQL語句使用的存儲庫模式。不知道放在哪裏DataContext.Dispose()方法,我把它放在SubmitChanges()功能由兩行代碼:

public void SubmitChanges() 
{ 
    db.SubmitChanges(); 
    db.Dispose(); 
} 

這是要做到這一點還是我這樣做完全錯誤的好地方?

+1

難道不該'db.Dispose()'? – 2010-11-15 23:07:25

+0

對不起,我有一個叫做Dispose()的函數,它叫做db.Dispose()。編輯。 – Darcy 2010-11-16 13:42:54

回答

2

一些挖後嗯,我遇到了這個帖子:

http://stephenwalther.com/blog/archive/2008/08/20/asp-net-mvc-tip-34-dispose-of-your-datacontext-or-don-t.aspx

,並在評論部分克雷格斯頓茨寫道:

未按規定處置其實現IDisposable通常會導致一個對象該對象將進入最終化隊列(請閱讀Jeffrey Richter的Applied Microsoft .NET Framework Programming的第19章以瞭解詳細信息)。這樣做的結果是,一個對象的內存可能在第01代中被釋放,直到後一代收集。如果你創造了很多這些對象,那就算算數學吧。

所以,你應該總是處置其實現IDisposable的任何對象。

對於控制器和DataContexts,事實證明這非常簡單,因爲Controller還實現了IDisposable,因此具有可以覆蓋的虛擬Dispose方法。所以你不必在使用中包裝你使用DataContext。您可以在構造函數(或任何地方)中創建它,然後在重寫的Controller.Dispose中進行處理。在這種情況下,在視圖中使用IQueryable工作得很好,因爲在呈現View之前,框架不會配置Controller。

所以我做了Craig的建議,並覆蓋了Controller繼承的Dispose方法。

在我的控制器代碼的頂部:

Repository repository; 

    // Default Contructor 
    public MyController() 
    { 
     repository = new Repository(); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     repository.Dispose(); 
    } 

,在我的倉庫我有一個名爲Dispose方法,看起來像:

public void Dispose() 
    { 
     db.Dispose(); 
    } 

其中db是我DataContext

現在我重寫的Dispose方法被調用每一次:),我沒有換我所有的ActionResult使用塊

+0

你有沒有在代碼中明確地調用控制器的重載Dispose方法?還是隱含地照顧? – stackPusher 2015-09-26 17:10:02

7

如果實現IDisposable做到這一點最簡單的方法是:

using(var context = new DataContext()){ 
    blah blah 
} 

這將確保它被設置在適當的時間。

  1. 打開它。
  2. 做你需要做的。
  3. 關閉它。

這樣你就不必擔心它四處張望,並沒有得到調用,因爲異常等

The dispose key word (MSDN Link)的。

由於它們是相關的,因此這裏是一個關於Dispose and Finalize的鏈接。聽起來就像在這種情況下,你想實現存儲庫,以便它實現IDisposable。這樣調用對象可以創建它,做它需要做的事情並關閉它。然後你可以清理數據上下文,當它被處置/最終化。

+0

這意味着我必須在每個ActionResult中正確地做到這一點?據我所知,您不能在存儲庫級別執行此操作,因爲上下文位於類級別。不用編輯1000個方法將會很好 – Darcy 2010-11-15 22:38:46

+0

然後你想讓倉庫實現IDisposable,這樣它就可以在完成時被處理。你應該實現一個終結器等來處理你的開放連接等。看看我在Dispose和Finalize上的鏈接,它會告訴你如何實現它。 – kemiller2002 2010-11-15 22:40:31

1

DataContext(資源庫)必須實現IDisposable

理想情況下,你需要一個UnitOfWork傳遞到存儲庫和實現IDisposable。在這裏你將它留給客戶去調用另一種方法,即不好

0

看一看here瞭解更多信息。