views:

986

answers:

6

Hi,

In a try/catch/finally block like:

try
{

}
catch()
{
   // code fails here
}
finally
{ 

}

So if there is an exception in the catch block, will finally always get called?

What if there is no finally, will the code after the catch block get run?

+17  A: 

Assuming the process doesn't terminate abruptly (or hang, of course), the finally block will always be executed.

If there's no finally block, the exception from the catch block will just be thrown up the stack. Note that the original exception which caused the catch block to be executed in the first place will be effectively lost.

Stack overflow exceptions

As Jared noted, a stack overflow will cause the finally block not to be executed. I believe this terminates the program abruptly, but I could be wrong. Here's sample code:

using System;

public class Test
{    
    static void Main()
    {
        // Give the stack something to munch on
        int x = 10;
        try
        {
            Main();
            Console.WriteLine(x);
        }
        finally
        {
            Console.WriteLine("Finally");
        }
    }  
}

Results:

Process is terminated due to StackOverflowException.

Jon Skeet
I believe a true Stack Overflow exception can also prevent a finally from being run. I can't find the documentation for this off hand though.
JaredPar
@Jared: Yes, I think you're quite possibly right. OutOfMemoryException as well? Not sure on that. Will try to reproduce.
Jon Skeet
But does a StackOverflowException terminate the whole process abruptly? If so, it comes under my first check.
Jon Skeet
+5  A: 

The finally block will always get executed. If you exclude the finally block, and an exception occurs inside the catch block, then no code after the catch block will execute, because essentially you're catch block will fail and generate an unhandled exception itself.

Joseph
+4  A: 

Yes the finally will always be run

No the code after the catch block won't be run.

Even with a finally block any code following the finally block will not run.

AnthonyWJones
+1 for the code after finally not run
Sunny
+1  A: 

If there's an exception in the catch block, the finally will execute, but a new exception will be thrown. The catch block in which the exception occurred will not catch the exception, it will continue up the stack.

Lesson learned: don't do stuff in the catch block that can throw if you can help it; if you must, nest a try/catch block.

try
{

}
catch()
{
  try
  {
    // code fails here
  }
  catch
  {
    // handle that. Or not. 
  }
}
finally
{ 

}
Randolpho
A: 

If an exception occurs in the catch block, all the code in finally would still be executed. If there is an exception handler higher up in the stack (e.g. caller of this function), it will catch this exception. Else result in an unhandled exception and bring your app down.

The code after the point of exception in the catch block will not get called.

Gishu
+1  A: 

The finally block will always be executed. From MSDN:

The finally block is useful for cleaning up any resources allocated in the try block as well as running any code that must execute even if there is an exception. Control is always passed to the finally block regardless of how the try block exits.

Whereas catch is used to handle exceptions that occur in a statement block, finally is used to guarantee a statement block of code executes regardless of how the preceding try block is exited.

By the way, this is the type of question that you can easily test yourself by writing some code, compiling it, and seeing what happens when you execute it.

class Program {
    static void Main(string[] args) {
        try {
            Console.WriteLine("Trying!");
            throw new Exception();
        }
        catch (Exception e) {
            Console.WriteLine("Catching {0}!", e.Message);
            throw new Exception();
        }
        finally {
            Console.WriteLine("Finally!");
        }
    }
}

This outputs:

Trying!
Catching Exception of type 'System.Exception' was thrown.!

Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at TestFinally.Program.Main(String[] args) in C:\Documents and Settings\Me\My
Documents\Visual Studio 2008\Projects\TestFinally\TestFinally\Program.cs:line 15
Finally!
Press any key to continue . . .

Jason