Why Use Finally in C#

Why use finally in C#?

The code inside a finally block will get executed regardless of whether or not there is an exception. This comes in very handy when it comes to certain housekeeping functions you need to always run like closing connections.

Now, I'm guessing your question is why you should do this:

try
{
doSomething();
}
catch
{
catchSomething();
}
finally
{
alwaysDoThis();
}

When you can do this:

try
{
doSomething();
}
catch
{
catchSomething();
}

alwaysDoThis();

The answer is that a lot of times the code inside your catch statement will either rethrow an exception or break out of the current function. With the latter code, the "alwaysDoThis();" call won't execute if the code inside the catch statement issues a return or throws a new exception.

What is the purpose of finally in try/catch/finally

In your example, it doesn't make a whole lot of difference.

Picture this, though:

    try
{
Console.WriteLine("Executing the try statement.");
throw new NullReferenceException();
}
catch (SomeOtherException e)
{
Console.WriteLine("{0} Caught exception #1.", e);
}
finally
{
Console.WriteLine("Executing finally block.");
}

Console.WriteLine("Executing stuff after try/catch/finally.");

In this case, the catch won't catch the error, so anything after the whole try/catch/finally will never be reached. However, the finally block will still run.

Is finally block in C# a must?

In your first example, you could re-throw the exception and the code inside the finally would still run. This would not be possible in the second example.

If you choose not to re-throw the exception, then yes there is little difference. However, this is considered bad form - very rarely should you need to consume an exception that you cannot explicitly handle.

It is a keyword to help you with code execution flow. When you throw an exception the execution flow of the code is affected (like using return), the finally keyword allows you to express that when an exception occurs (or you return from a try) you still want execution to do something as it's leaving.

To answer the question facetiously, it is a must when you need it and not when you don't.



Further Reading

To be on the safe side, before you attempt to start making use of this keyword, please read the documentation for it:

http://msdn.microsoft.com/en-us/library/zwc8s4fz.aspx

And the exception handling keywords in general:

http://msdn.microsoft.com/en-us/library/s7fekhdy.aspx



Examples

Catch an exception to do something with it, then re-throw it. Use finally to call any tidy-up code:

try
{
OpenConnectionToDatabase();
// something likely to fail
}
catch (Exception ex)
{
Log(ex);
throw;
// throw ex; // also works but behaves differently
}
// Not specifying an exception parameter also works, but you don't get exception details.
//catch (Exception)
//{
// Log("Something went wrong);
// throw;
//}
finally
{
CloseConnectionToDatabase();
}

Don't register any interest in catching exceptions, but use finally to tidy-up code:

try
{
OpenConnectionToDatabase();
// something likely to fail
}
finally
{
CloseConnectionToDatabase();
}

Return from your try because it looks nicely formatted, but still use finally to tidy-up code:

try
{
OpenConnectionToDatabase();
return 42;
}
finally
{
CloseConnectionToDatabase();
}

Where the finally is necessary?

Update: This is actually not a great answer. On the other hand, maybe it is a good answer because it illustrates a perfect example of finally succeeding where a developer (i.e., me) might fail to ensure cleanup properly. In the below code, consider the scenario where an exception other than SpecificException is thrown. Then the first example will still perform cleanup, while the second will not, even though the developer may think "I caught the exception and handled it, so surely the subsequent code will run."


Everybody's giving reasons to use try/finally without a catch. It can still make sense to do so with a catch, even if you're throwing an exception. Consider the case* where you want to return a value.

try
{
DoSomethingTricky();
return true;
}
catch (SpecificException ex)
{
LogException(ex);
return false;
}
finally
{
DoImportantCleanup();
}

The alternative to the above without a finally is (in my opinion) somewhat less readable:

bool success;

try
{
DoSomethingTricky();
success = true;
}
catch (SpecificException ex)
{
LogException(ex);
success = false;
}

DoImportantCleanup();
return success;

*I do think a better example of try/catch/finally is when the exception is re-thrown (using throw, not throw ex—but that's another topic) in the catch block, and so the finally is necessary as without it code after the try/catch would not run. This is typically accomplished with a using statement on an IDisposable resource, but that's not always the case. Sometimes the cleanup is not specifically a Dispose call (or is more than just a Dispose call).

Actual use of finally block

The GC will clear managed resources (objects your application has created in memory) when they are no longer referenced. This doesn't include things like file handles, network resources, database connections etc... You must clear them up yourself in the finally block or risk them not clearing (although most will clear eventually).

OR, more commonly:

Many classes which which unmanaged resources to be disposed of implement the IDisposable interface. This means you can wrap the code in a using block and be sure that the unmanaged resources will be cleared (it calls the object's Dispose() method when it goes out of scope).

A good example of using the finally block is when you use an Office interop library. Say you open Microsoft Word, run some code, code fails...Word will always need closing regardless of whether an error occurred or not. Therefore I would put the closing code in the finally block.

How does the try catch finally block work?

Yes, the finally block gets run whether there is an exception or not.


Try
[ tryStatements ]
[ Exit Try ]
[ Catch [ exception [ As type ] ] [ When expression ]
[ catchStatements ]
[ Exit Try ] ]
[ Catch ... ]
[ Finally
[ finallyStatements ] ] --RUN ALWAYS
End Try

See: http://msdn.microsoft.com/en-us/library/fk6t46tz%28v=vs.80%29.aspx

Why is try {...} finally {...} good; try {...} catch{} bad?

The big difference is that try...catch will swallow the exception, hiding the fact that an error occurred. try..finally will run your cleanup code and then the exception will keep going, to be handled by something that knows what to do with it.

Use a 'try-finally' block without a 'catch' block

You would use it to ensure some actions occur after the try content or on an exception, but when you don't wish to consume that exception.

Just to be clear, this doesn't hide exceptions. The finally block is run before the exception is propagated up the call stack.

You would also inadvertently use it when you use the using keyword, because this compiles into a try-finally (not an exact conversion, but for argument's sake it is close enough).

try
{
TrySomeCodeThatMightException();
}
finally
{
CleanupEvenOnFailure();
}

Code running in finally is not guaranteed to run, however the case where it isn't guaranteed is fairly edge - I can't even remember it. All I remember is, if you are in that case, chances are very good that not running the finally isn't your biggest problem :-) so basically don't sweat it.

Update from Tobias: finally will not run if the process is killed.

Update from Paddy: Conditions when finally does not execute in a .net try..finally block

The most prevalent example you may see is disposing of a database connection or external resource even if the code fails:

using (var conn = new SqlConnection("")) // Ignore the fact we likely use ORM ;-)
{
// Do stuff.
}

Compiles into something like:

SqlConnection conn;

try
{
conn = new SqlConnection("");
// Do stuff.
}
finally
{
if (conn != null)
conn.Dispose();
}


Related Topics



Leave a reply



Submit