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.
