‘using’ IDisposable objects

This isn’t fully game related, but I see so many people posting code on forums that looks like this:

 Stream stream = storageContainer.CreateFile("MyFile.txt");
StreamWriter writer = new StreamWriter(stream);
writer.Write("Stuff");
writer.Close();
stream.Close();

I cringe at this sight.

IDisposable is an interface that objects leveraging native handles or resources will almost always implement to ensure the native resources are released properly and deterministically. If any of the code in there were to cause an exception, you’d risk not releasing those resources at that point. At best you’d see them released when a garbage collection occurred and at worst they wouldn’t get cleaned up at all.

Now, most people will respond with “but there’s so little going on there, what would throw an exception?” and that’s valid for this example, but a lot of games do a lot more in there. Things like serializing (or deserializing) objects, parsing strings into numbers, and so on. There are lots of places where file IO, state saving/loading, and other Stream manipulation can throw, so it’s always better to be on the side of safety rather than stubbornness.

Anytime a type implements IDisposable, that should be your hint to leverage the ‘using’ statement. In an unfortunate case, the ‘using’ keyword is not only used for including namespaces but also for scoping IDisposable objects so that they are guaranteed to be disposed. To reuse the example above, here’s the correct way to write that:

 using (Stream stream = storageContainer.CreateFile("MyFile.txt"))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        writer.Write("Stuff");
    }
}

Not only does this help scope your objects to prevent using either the stream or writer objects outside of their respective blocks, but it means that even if the code in the middle of the ‘using’ block throws an exception, the objects created in the ‘using’ statements are guaranteed to be disposed. Basically the compiler takes the above code and turns it into this:

 {
    Stream stream = storageContainer.CreateFile("MyFile.txt");
    try
    {
        StreamWriter writer = new StreamWriter(stream);

        try
        {
            writer.Write("Stuff");
        }
        finally
        {
            if (writer != null)
                ((IDisposable)writer).Dispose();
        }
    }
    finally
    {
        if (stream != null)
            ((IDisposable)stream).Dispose();
    }
}

(And yes, those extra curly braces are intended; they are used to scope the ‘stream’ object so it cannot be used outside of the ‘using’ block.)

As you can see this is much safer code than the first snippet because it removes the possibility of not disposing those objects and thus ensures that native resources will be properly released when you expect rather than when the next GC occurs or when your app shuts down.

So please, if you find yourself writing code similar to the first snippet, please stop doing that and start ‘using’ IDisposable objects properly. Winking smile