The “using” Statement and IDisposable

You may have seen some code like this:


using (StreamReader reader = File.OpenText("file.txt")) {
reader.ReadToEnd();
}

(If you haven’t seen this before, this code reads from the text file file.txt and dumps the contents into reader.)

You may wonder what the using statement does. This is exactly the same as:


StreamReader reader = File.OpenText("file.txt"));
reader.ReadToEnd();
reader.Close(); // aka reader.Dispose(true);

If you disassemble and dig into the StreamReader.Close() function, you may be surprised to find only one line:


public override void Close()
{
this.Dispose(true);
}

What is using(…) for? Let’s go back to our first code example. What would happen if we forgot to call reader.Close()? Well, the file handle that’s reading file.txt would never be garbage-collected; the operating system would always see something trying to access the file.

Really, what this means is that we have some code that needs to call some sort of de-initialization or clean-up to release some sort of managed resources. Other examples of resources like this could include a connection to a database, or perhaps a socket that’s open to read some data from a remote server.

The IDisposable interface was created to handle this case. All objects inherit a Finalize method from the Object class. The garbage collector calls this method before it releases the object from memory. IDisposable provides a method called Dispose, which allows you to specify code to occur before the object is garbage-collected. (Dispose, Finalize, and destructors are all related, but that’s beyond our scope of discussion here.)

Since Dispose() needs to be called before the object is collected, there’s a risk that if someone forgets to call it, some unmanaged resource might never be properly disposed of. That’s where using comes into place–when you close your using block, the Dispose method is automatically called sometime after the block ends.

When you implement Dispose(), the method call will be immediate. You don’t have to wait for your object to be garbage-collected; results happen right away. MSDN mentions this in their documentation page here.

This means that you can “use” (pun not intended) IDisposable resources, without having to worry about cleaning them up — just wrap them in a using block and the CLR takes care of the rest! This definitely makes your life easier in situations where you use and dispose of a resource in a single method block.

And finally, you can even create multiple IDisposable objects in a single using statement, like so:


using (StreamReader reader = File.OpenText("file.txt"),
FileStream writer = File.OpenWrite("copy.txt")) {
// ...
}

A little-known, but useful tip for those corner-case situations.

About Ashiq Alibhai, PMP

Ashiq has been coding C# since 2005. A desktop, web, and RIA application developer, he's touched ASP.NET MVC, ActiveRecord, Silverlight, NUnit, and all kinds of exciting .NET technologies. He started C# City in order to accelerate his .NET learning.
This entry was posted in Core .NET, Silverlight, Web, Wndows Forms and tagged , , , . Bookmark the permalink.

4 Responses to The “using” Statement and IDisposable

  1. terrorix says:

    Im interesting in this words> …the Dispose method is automatically called sometime after the block ends. (It may not be immediate; it depends on the CLR.)…
    Can you provide more details, sources about this ? Because it seems that we have problems especially with some delays when using block ends } and when Dispose method is really called.

  2. Lasse V. Karlsen says:

    Actually, the call to `Dispose` will always happen as part of the generated code substituted for the end-brace of the using construct, there’s no delay involved at all.

    If you have this code:

    using (var x = …)
    {
    // code piece y
    }
    // code piece x

    Then Dispose will be called between code piece y and code piece x, there’s no “depends” involved at all, it’s part of the contract.

    Also see http://stackoverflow.com/questions/4060684/using-statement-on-idisposable-object-delay-of-calling-dispose-method

  3. Ashiq Alibhai, PMP says:

    @terrorix looks like Lasse V. Karlsen is correct. The official spec says that Dispose is called immediately, which may be more beneficial then NOT using IDisposable (in which case, Dispose is called when garbage collection occurs, which is non-deterministic).

    I’ve updated the article to mention these points.

  4. terrorix says:

    @Ashiq, thanks for explanation and update.

Leave a Reply

Your email address will not be published. Required fields are marked *