Understand C#: Proper use IDisposable and using keyword
The System.IDisposable interface is a very useful interface to understand if you are concerned about performance in your application. Microsoft says the following about the IDisposable interface:
The garbage collector automatically releases the memory allocated to a managed object when that object is no longer used, however, it is not possible to predict when garbage collection will occur. Furthermore, the garbage collector has no knowledge of unmanaged resources such as window handles, or open files and streams.
Most System.Data, System.IO and System.Windows.Controls objects use the IDisposable interface, as well as many others, to free up unmanaged resources that may have been created when the object was initialized. Unmanaged resources are any calls that are made outside of the .NET environment, this can be GDI+ calls, SQL Driver calls, Disk IO calls, or basically anything that cannot be accounted for by the Garbage Collector.
Often times you will see database connection code that looks like this:
SqlConnection conn = new SqlConnection("{connection string}");
SqlCommand command = new SqlCommand(conn);
command.CommandText = "select * from SomeTable";
// ... some more code to use the command
conn.Close();
However there are a problem with this code, the unmanaged resources for the SQL connection have not yet been destroyed in memory. The correct way this code should have been written is the following:
using (SqlConnection conn = new SqlConnection("{connection string}")) {
using (SqlCommand command = conn.CreateCommands()) {
command.CommandText = "select * from SomeTable";
// ... some more code to use the command
conn.Close();
}
}
And if you were to look at this code under a microscope the following code is actually what is happening:
SqlConnection conn;
SqlCommand command
try {
conn = new SqlConnection("{connection string}");
command = new SqlCommand(conn);
command.CommandText = "select * from SomeTable";
// ... some more code to use the command
} finally {
conn.Close();
command.Dispose();
conn.Dispose();
}
So essentially even if an exception is thrown from your code, the unmanaged code is still cleaned up and you don’t have memory leaks from unmanaged code sitting around in memory waiting to be reclaimed. It is reclaimed instantly after you are done working with it.
If you would like to learn more about the code used above please see these links
Tags: .Net, Framework 1.0
Social: |
| View blog reactions









October 2nd, 2007 at 12:33 pm
The .Dispose() method of the SqlConnection calls the .Close() method implicitly, so you don’t have to call .Close() explicitly if you call Dispose(). And I believe “using” calls Dispose() implicitly, and in turns it calls Dispose().
See: http://msdn2.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection(vs.80).aspx
October 2nd, 2007 at 12:50 pm
Yes I know that .Dispose() calls the .Close() in most cases of the stream and connections. However out of practice I just call them. Yes the using block does call .Dispose(), and that is pretty much the main function of the using block. But most of what I wrote above is just good practice, because you always want to call the .Close() right after you are done with the database, even if the bottom of the using block is right below it or 30 lines below it.
October 3rd, 2007 at 12:03 am
Calling Close sometimes helps for some reason even though the Using block or Dispose is supposed to do it automatically. I’ve seen this with FileStream objects in a web service where I would have file locking problems if I didn’t call Close before the end of the Using block. It doesn’t make sense but until I added that line I had the problem and I didn’t afterward.
October 3rd, 2007 at 8:56 am
Frank,
That is why I always just call it to be on the safe side of things.