Exception handling and resource protection with try..finally
Paul Sheriff has just published an example he uses to recommend the use of try..finally blocks. Here is his example:
private void CreateLogFile()
{
try
{
StreamWriter sw =
new StreamWriter(@"D:\Samples\Test.txt",
true, System.Text.UTF8Encoding.UTF8);
sw.WriteLine("This is some text");
sw.Close();
}
catch(Exception ex)
{
throw ex;
}
}
Here is how I'd rewrite this example if we want to stick to try..finally:
private void CreateLogFile()
{
StreamWriter writer;
writer = new StreamWriter(@"D:\Test.txt",
true, System.Text.UTF8Encoding.UTF8);
try
{
writer.WriteLine("This is some text");
}
finally
{
writer.Dispose();
}
}
Why would I rewrite the example this way?
- No need to protect resources that haven't been allocated. The
finally block is useful only if the creation of the writer works. So
the try..finally block should start immediately after that, not before.
See http://weblogs.asp.net/fmarguerie/archive/2004/08/13/214135.aspx - Use "throw", not "throw ex". If you use "throw ex", you lose the
original stack trace.
See http://www.tkachenko.com/blog/archives/000352.html - The "catch" block is useless here because it does nothing except letting the exception flow.
- No need to test if (writer != null) because if we are in the finally
block the writer has been created successfully. If the writer is not created, the finally block is never executed because we'd get out of the method due to an exception before the try..finally block.
- It's better to use Dispose in most cases. It calls Close and may perform other cleaning operations. Close is just fine in this example, though.
Of course, we can use the using pattern to make the code even better:
private void CreateLogFile()
{
using (StreamWriter writer = new StreamWriter(@"D:\Test.txt",
true, System.Text.UTF8Encoding.UTF8))
{
writer.WriteLine("This is some text");
}
}
Note that VB has Using too now.