Using the using statement
September 19, 2008
With .NET we have the garbage collector to clean up all the mess we make through the lifecycle of an application. But does that mean that we will never have to clean up anything our self? Not really. As a general rule, classes which implements the IDisposable interface should be manually disposed, usually by calling a Close() or Dispose() method on the instance. It could look a bit like this:
StreamReader sr = new StreamReader(@"C:\temp\myfile.txt");
while(!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
sr.Close();
As you can see, we call the Close() method in the end - if we don’t do that, an unmanaged reference to the file will be kept open, which is something we really don’t want. However, you might have lots of lines of code working with the file, and in the end, you forget to dispose of the object. The using statement in C# can help prevent this, and also comes with another benefit, explained after this example of using it:
using(StreamReader sr = new StreamReader(@"C:\temp\myfile.txt"))
{
while(!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
}
As you can see, there are no explicit call to the Close() method - the using statement takes care of it for us. Since it has its own scope, the .NET framework knows that once this scope ends, the object(s) declared in the using statement can be disposed. You can even have several using statements for one block, like this:
using(Pen p = new Pen(Color.Black, 2))
using(SolidBrush sb = new SolidBrush(Color.Red))
{
// Do stuff with p and sb here
}
As mentioned, the using statement comes with another advantage: It works as a try..finally block too! In the first two examples, an exception could easily occur, because we were dealing with files and doing no error checking at all. In the first example, an exception would cause the execution of the code to end, and the reference to the file would not be closed! This could be solved by creating the file reference within a try block, and then calling the Close() method in the finally block, but in fact, the using() statement does just that for us automatically, meaning that you can be sure that objects instantiated in a using statement will be disposed, no matter what!
So in conclusion: Use the using statement!