I've been getting lots of connection pool timeouts in my ASP.NET MVC project. I've been reading that even though Linq-to-SQL should be disposing for me it doesn't always work and also that not manually disposing anything that inherits IDisposable
is bad practice.
I'm using the repository pattern that all my Linq-to-SQL statements use. Not knowing where to put the DataContext.Dispose()
method, I put it in the SubmitChanges()
function that consists of two lines of code:
public void SubmitChanges()
{
db.SubmitChanges();
db.Dispose();
}
Is this a good place to do this or am I doing it completely wrong?
If it implements IDisposable the easiest way to do it is:
using(var context = new DataContext()){
blah blah
}
This ensures it is disposed at the appropriate time.
This way you don't have to worry about it hanging around, and not getting called because of an exception etc.
The dispose key word (MSDN Link).
Since they are related, here is a link about Dispose and Finalize. It sounds like in this case, you want to implement the Repository so that it implements IDisposable. This way the calling object can create it, do what it needs to do and close it. You then can clean up the data context when it is disposed/finalized.
Well after some more digging I came across this post:
http://stephenwalther.com/blog/archive/2008/08/20/asp-net-mvc-tip-34-dispose-of-your-datacontext-or-don-t.aspx
and in the comments section Craig Stuntz wrote:
Failing to Dispose an object which implements IDisposable typically results in the object going into the finalization queue (read Chapter 19 of Jeffrey Richter's Applied Microsoft .NET Framework Programming for details). The results of this is that an object's memory that might have otherwise been freed in generation 01 be freed until a later generation collection. If you're creating a lot of these objects, well, do the math.
So you should always Dispose any object which implements IDisposable.
In the case of Controllers and DataContexts, this turns out to be really easy, because Controller also implements IDisposable, and hence has a virtual Dispose method you can override. So you don't have to wrap your use of DataContext in a using. You can create it in the constructor (or wherever) and then dispose in the overridden Controller.Dispose. In this case, using IQueryable in the view works just fine, because the framework does not Dispose the Controller until the View has been rendered.
So I did what Craig suggested and overrode the Dispose method that the Controller
inherits.
At the top of my controller code:
Repository repository;
// Default Contructor
public MyController()
{
repository = new Repository();
}
protected override void Dispose(bool disposing)
{
repository.Dispose();
}
and in my Repository I have a method called Dispose that looks like:
public void Dispose()
{
db.Dispose();
}
where db is my DataContext
.
Now my overriden Dispose method gets called every time :) and I don't have to wrap all my ActionResult
in using blocks
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With