Using the using-statement

“Using statement?”, you may ask. “What is so interesting about that? I use it every day importing tons of namespaces!”

Well, i mean the other using statement; that one that results in a nice try..finally in IL, without having to write lots of code.

Well lets say you want to access a file, a database, or whatever resource that needs to be closed after usage:

StreamReader sr = new StreamReader(@"c:\mytextfile.txt");
sr.ReadToEnd().Count(); // just doing something
sr.Close(); // closing a resource explicitly. gooood!
The problem here is: If the file for example is not encoded correctly, or you’re just doing something inbetween opening and closing your reader that might fail, you’re resource will not be closed until the GC disposes it. This in some cases might mean, until your application is closed.
Putting a try catch arround it helps:
StreamReader sr = null;
try
{
  sr = new StreamReader(@"c:\mytextfile.txt");
  sr.ReadToEnd().Count(); // just doing something
}
finally
{
  if (sr != null) // StreamReader.ctr() could fail...
  sr.Close();
}

The using statement does exactly the same. The IL-Code also looks pretty similar, but it is way easier to write.

using(StreamReader sr = new StreamReader(@"c:\my.txt"))
{
  sr.ReadToEnd().Count(); // just doing something
}
The using-statement takes any object implementing IDisposable. In the end or in case of any error, it will safely dispose the used resource. The Dispose()-Method on Streams or any other Reader/Writer in usually does the same thing as Close() does.
You can even nest them if you have to use multiple resource at once:
using(StreamReader sr1 = new StreamReader(@"c:\my1.txt"))
using (StreamReader sr2 = new StreamReader(@"c:\my2.txt"))
using (StreamWriter sw = new StreamWriter(@"c:\mynew.txt"))
{
  sw.WriteLine(sr1.ReadToEnd());
  sw.WriteLine(sr2.ReadToEnd());
}

Almost any resource usage in .Net, for example ADO.Net implements the IDisposable on their classes. The connection will be closed and disposed, the transaction will be rolled back if something fails before commit.

using (var conn = new SqlConnection("..."))
{
  using (var st = conn.BeginTransaction())  
  {
    conn.Open();
  var sc = conn.CreateCommand();
    sc.CommandText = "UPDATE ...";
    sc.ExecuteNonQuery();
  var sc2 = conn.CreateCommand();
    sc2.CommandText = "SELECT ...";
    using (var reader = sc2.ExecuteReader())
  {
  return reader.GetString(0);
  }
  st.Commit();
  }
}

Have fun!

Note:There is no guarantee, that IDisposable.Dispose() on classes you find in .NET or other libraries will close everything as necessary. On the WCF clients, for instance, you need to call Abort() instead of Close() or Dispose() in case of an communication error, otherwise your connection will stay opened.

If you’re in doubt on a certain class, just use Reflector to check its behaviour.

Updated: Other Resources

kick it on DotNetKicks.com

Advertisements

9 thoughts on “Using the using-statement

  1. Hey,
    Thanks for the nice article!
    It had reinvented my whole understanding of the using() statement – it’s actually just a helper statement!

    Jacob

  2. Pingback: Dew Drop - April 19, 2008 | Alvin Ashcraft's Morning Dew

  3. Hey,

    Its a nice article!!

    But perhaps, you may want to add a little section there, just to elaborate on the disadvantage of using the “Using directive” w.r.to Connection pooling while using Connection objects.

    That may be useful for young developers.

    Thanks,
    Kaushik R

  4. Hi Kaushik,

    i’ve heard about theese problems, but I myself have never experienced them. I neither understand how there could be any problems.

    SqlConnection.Dispose() sets the _poolGroup-Field to null before calling Close. But Close does not accesse it, so there should not be any impact.

    At least, if there is an issue, it’s a bug, IMHO.

    regards,
    Lars

  5. I wrote about this on my site a few days ago, but your post is better. I was delighted when I learned that you could chain using statements–of course, that can cause problems with complexity and trying to do too many files at once.

  6. Pingback: Free .Net Ambient Context Pattern Implementation « .Net Braindrops

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s