Search code examples
c#using

Are usings guarding for all eventualities?


I've found the following passage.

using (TextWriter w1 = new StringWriter(...))
using (XmlWriter w2 = new XmlTextWriter(w1))
using (StringReader r1 = new StringReader(...))
using (XmlTextReader r2 = new XmlTextReader(r1))
{
  _xslt.Transform(r2, w2);
  ...
  FileOperations.LockFiles();

  w1.Close();
  w2.Close();
  r1.Close();
  r2.Close();
}

My suggestion is (besides renaming, of course) that we could remove the last four statements, since those are declared using using and will be closed and disposed properly when the framework feels like it.

However, one of the developers questioned me and asked a very disturbing question. "Are you entirely sure?". Then I got chicken feet and postponed the answer. Is there anything I could be missing?


Solution

  • Yes, the using blocks will always dispose the objects, no matter what. (Well, short of events like a power outage...)

    Also, the disposing of the objects is very predictable, that will always happen at the end of the using block. (Once the objects are disposed, they are removed from the finalizer queue and are just regular managed objects that can be garbage collected, which happens when the garbage collector finds it convenient.)

    In contrast, the Close calls will only be called if there are no unhandled exceptions inside the block. If you wanted them to surely be executed you would place them in finally blocks so that they are exected even if there is an exception. (That's what the using blocks are using to make sure that they can always dispose the objects.)