#911 – finally Block Execution When Exception Is Rethrown

Recall that if an exception is caught in a catch block, an associated finally block will execute after the execution of the catch block.

If the catch block rethrows the exception, the finally block will execute after the catch block, but before the exception propagates back up the call stack.

In the example below, the sequence is:

  • Exception thrown from try block in HelperMethod
  • Exception caught in catch block in HelperMethodcatch block executes up to throw
  • finally block in HelperMethod executes
  • Exception caught in catch block of Main method
        static void Main(string[] args)
        {
            try
            {
                HelperMethod();
            }
            catch
            {
                Console.WriteLine("Caught exception in Main()");
            }

            Console.ReadLine();
        }

        static void HelperMethod()
        {
            try
            {
                throw new ApplicationException("Uh-oh");
            }
            catch
            {
                Console.WriteLine("In catch block, before re-throwing");
                throw;
            }
            finally
            {
                Console.WriteLine("In finally block");
            }
        }

911-001

Advertisement

#910 – One Example of a finally Block

You use a finally block when you have logic that should execute whether or not an exception occurs when executing a block of code.

One example of something that you might do in a finally block is to call a Dispose method on an object that implements IDisposable.  You would do this because you want to make sure that you always call Dispose on the disposable object, whether or not an exception occurs when using the object.

(Note: You can achieve the same pattern with the using statement, which automates invocation of a Dispose method).

            StreamWriter sw = new StreamWriter(@"D:\Log.txt");
            try
            {
                sw.Write(string.Format("Did something at {0}", DateTime.Now));
            }
            finally
            {
                sw.Dispose();
            }

#909 – When a finally Block Executes

The purpose of a finally block is to define some code that should always execute, whether or not an exception occurs while executing code in the corresponding try block.

Exactly when a finally block executes depends on several things:

  • If the code in the try block executes without throwing an exception or transferring control elsewhere
    • The finally block executes after the code in the try block
  • If an exception occurs while executing code in the try block ..
    • .. and the exception is caught in a catch block associated with the same try statement — the body of the catch block executes, followed by the body of the finally block
    • .. and the exception is not caught — the body of the finally block executes before the exception propagates back up the call stack
  • If a goto or return statement is encountered in the try block
    • The finally block executes before control is transferred

#864 – An Example of a finally Block with No catch Block

When an exception occurs while executing code in a try block that has an associated finally block, the code in the finally block will execute before the exception bubbles up the call stack.

Below is an example.  MethodA calls MethodB, which in turn calls MethodC.  MethodC throws an exception.  When this happens, the code in MethodB’s try block is interrupted and the code in the finally block is executed.  The exception then bubbles up the call stack, where it is then caught by the catch block in MethodA.

        private static void MethodA()
        {
            try
            {
                MethodB();
                Console.WriteLine("After MethodB call");
            }
            catch (Exception xx)
            {
                Console.WriteLine("Exception caught in MethodA!");
            }

            Console.WriteLine("Finishing up MethodA");
        }

        private static void MethodB()
        {
            try
            {
                Console.WriteLine("Before MethodC() call");
                MethodC();
                Console.WriteLine("After MethodC() call");
            }
            finally
            {
                Console.WriteLine("MethodB() finally block");
            }

            Console.WriteLine("Finishing up MethodB()");
        }

        private static void MethodC()
        {
            throw new Exception("Uh-oh");
        }

864-001

#863 – How a finally Block Works with No catch Block

When you include a finally block with some code that’s surrounded by a try block, you’re saying that you want the code in the finally block to run after the code in the try block, whether or not an exception occurs.

If no exception occurs while executing the statements in the try block, the statements in the finally block simply execute after the code in the try block.

If an exception does occur and you have a finally block, but no catch block, the following happens:

  • Some of the code in the try block executes, up to the point where the exception occurred
  • The code in the finally block executes
  • The exception continues bubbling up the call stack
  • Code in the current method that’s located after the finally block does not execute

#862 – Options for Including catch and finally Blocks

When you define a try block using the try keyword, you must also do one of the following:

  • Include one or more catch blocks after the try block
  • Include a finally block after the try block
  • Include one or more catch blocks after the try block, followed by a finally block

Whether you include a catch block, a finally block, or both, depends on what you want to accomplish:

  • Include catch blocks to intercept and act upon exceptions that got thrown as a result of executing the code in the try block.
  • Include a finally block if there are things that need to happen (like releasing resources), regardless of whether or not an exception occurs.
  • Include both catch and finally blocks if both statements above are true.

#861 – A finally Block Always Executes

When you use a try block, you’re defining a block of code for which you can catch an exception, using a catch block.  You can also include a finally block, which dictates a block of code that will execute whether or not an exception occurs.

Suppose that you have the following code:

                try
                {
                    Console.WriteLine("BEFORE the call");
                    SomeMethod();
                    Console.WriteLine("AFTER the call");
                }
                catch (Exception exc)
                {
                    Console.WriteLine("Exception caught in catch block");
                }
                finally
                {
                    Console.WriteLine("Code in finally block executing");
                }

If an exception does not occur, all of the code in the try block will execute, followed by all of the code in the finally block.

861-001

 

If the SomeMethod method throws an exception, the code in the try block after the call to SomeMethod will not execute.  Instead, the code in the catch block will execute, followed by the code in the finally block.

861-002