I understand how try-catch works and how try-finally works, but I find myself using those (usually) in two completely different scenarios:
using
in C# and VB) is mostly used around some medium-sized code block that uses some resource that needs to be disposed properly.In my experience, cases where a try-catch-finally would be appropriate, i.e., where the block in which I want to catch some particular exception is exactly the same block in which I use some disposable resource, are extremely rare. Yet, the language designers of C#, VB and Java seem to consider this to be a highly common scenario; the VB designers even think about adding catch to using
.
Am I missing something? Or am I just overly pedantic with my restrictive use of try-catch?
EDIT: To clarify: My code usually looks like this (functions unrolled for clarity):
Try
do something
Aquire Resource (e.g. get DB connection)
Try
do something
Try
do something that can fail
Catch SomeException
handle expected error
do something else...
Finally
Close Resource (e.g. close DB connection)
do something
Catch all
handle unexpected errors
which just seems to make much more sense than putting any of the two catches on the same level as finally just to avoid indentation.
A quote from MSDN
A common usage of catch and finally together is to obtain and use resources in a try block, deal with exceptional circumstances in a catch block, and release the resources in the finally block.
So to make it even more clear, think of the code that you want to run, in 99% of the cases it runs perfectly well but somewhere in the chunk there might occure an error, you don't know where and the resources created are expensive.
In order to be 100% sure that the resources are disposed of, you use the finally block, however, you want to pin-point that 1% of cases where the error occures, therefore you might want to set up logging in the catch-ing-section.
That's a very common scenario.
Edit - A Practical Example
There is some good examples here: SQL Transactions with SqlTransaction Class. This is just one of the many ways to use Try, Catch & Finally and it demonstrates it very well, even though a using(var x = new SqlTranscation)
might be efficient some times.
So here goes.
var connection = new SqlConnection();
var command = new SqlCommand();
var transaction = connection.BeginTransaction();
command.Connection = connection;
command.Transaction = transaction;
Here comes the more interesting parts
///
/// Try to drop a database
///
try
{
connection.Open();
command.CommandText = "drop database Nothwind";
command.ExecuteNonQuery();
}
So let's imagine that the above fails for some reason and an exception is thrown
///
/// Due to insufficient priviligies we couldn't do it, an exception was thrown
///
catch(Exception ex)
{
transaction.Rollback();
}
The transaction will be rolled back! Remember, changes you made to objects inside the try/catch will not be rolled back, not even if you nest it inside a using!
///
/// Clean up the resources
///
finally
{
connection.Close();
transaction = null;
command = null;
connection = null;
}
Now the resources are cleaned up!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With