Does the C# "finally" block ALWAYS execute?

C#Try Catch

C# Problem Overview


> Possible Duplicate:
> Will code in a Finally statement fire if I return a value in a Try block?

Consider the following code C# code. Does the "finally" block execute?

public void DoesThisExecute() {
   string ext = "xlsx";
   string message = string.Empty;
   try {
      switch (ext) {
         case "xls": message = "Great choice!"; break;
         case "csv": message = "Better choice!"; break;
         case "exe": message = "Do not try to break me!"; break;
         default:
            message = "You will not win!";
            return;
      }
   }
   catch (Exception) {
      // Handle an exception.
   }
   finally {
      MessageBox.Show(message);
   }
}

Ha, after I got done writing this, I realized I could have done tested this myself in Visual Studio. However, please feel free to answer!

C# Solutions


Solution 1 - C#

No it does not. It will always execute provided the application is still running (except during a FastFail exception, MSDN link, like others noted). It will execute when it exits the try/catch portion of the block.

It will NOT execute if the application crashes: gets killed through a kill process command etc. This is highly important, because if you write code that absolutely expects it to run, like manually doing a roll back, and if not other wise it will automatically commit, you can run into a scenario the application aborts before that happens. Honestly, this is an outside scenario, but it is important to take note of in those situations.

Solution 2 - C#

From MSDN C# specification of the try statement:

> The statements of a finally block are always executed when control leaves a try statement. This is true whether the control transfer occurs as a result of normal execution, as a result of executing a break, continue, goto, or return statement, or as a result of propagating an exception out of the try statement.

Source

There are the cases where the finally block will not execute:

  1. Environment.FailFast
  2. Uncatchable exception types
  3. Power Failure

Solution 3 - C#

It is not totally true that finally will always be executed. See this answer from Haacked:

> Two possibilities: > > - StackOverflowException > - ExecutingEngineException > > The finally block will not be executed > when there's a StackOverflowException > since there's no room on the stack to > even execute any more code. It will > also not be called when there's an > ExecutingEngineException, which is > very rare.

In fact, for any sort of asynchronous exception (like StackOverflowException, OutOfMemoryException, ThreadAbortException) the execution of a finally block is not guaranteed.

However, these exceptions are exceptions you usually cannot recover from, and in most cases your process will exit anyway.

In fact, there is also at least one other case where finally is not executed as described by Brian Rasmussen in a now deleted question:

> The other case I am aware of is if a > finalizer throws an exception. In that > case the process is terminated > immediately as well, and thus the > guarantee doesn't apply. > > The code below illustrates the problem

static void Main(string[] args) {
   try {
      DisposableType d = new DisposableType();
      d.Dispose();
      d = null;
      GC.Collect();
      GC.WaitForPendingFinalizers();
   } catch {
      Console.WriteLine("catch");
   } finally {
      Console.WriteLine("finally");
   }
}

public class DisposableType : IDisposable {
   public void Dispose() {
   }

   ~DisposableType() {
      throw new NotImplementedException();
   }
}

A reliable try/catch/finally will have to use Constrained Execution Regions (CER). An example is provided by MSDN:

[StructLayout(LayoutKind.Sequential)]
struct MyStruct
{
    public IntPtr m_outputHandle;
}

sealed class MySafeHandle : SafeHandle
{
    // Called by P/Invoke when returning SafeHandles
    public MySafeHandle()
        : base(IntPtr.Zero, true)
    {
    }

    public MySafeHandle AllocateHandle()
    {
        // Allocate SafeHandle first to avoid failure later.
        MySafeHandle sh = new MySafeHandle();

        RuntimeHelpers.PrepareConstrainedRegions();
        try { }
        finally
        {
            MyStruct myStruct = new MyStruct();
            NativeAllocateHandle(ref myStruct);
            sh.SetHandle(myStruct.m_outputHandle);
        }

        return sh;
    }
}

An excellent source of information is the following article:

> Reliability Best Practices

Solution 4 - C#

From MSDN try-finally (C# Reference)

> 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.

Solution 5 - C#

Solution 6 - C#

Yes, under normal circumstances (as many others have pointed out).

> 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.

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

Solution 7 - C#

The finally block will run, right between these lines:

message = "You will not win!";
return;

Solution 8 - C#

Yes, finally always executes, now whether or not the code in the finally block will cause an exception is a different story.

Solution 9 - C#

No it doesn't.

There's only a single way around it though and that is Environment.FailFast(). See http://msdn.microsoft.com/de-de/library/ms131100.aspx. In every other case it is guaranteed that finalizers get executed ;-)

> The FailFast method writes the message > string to the Windows Application > event log, creates a dump of your > application, and then terminates the > current process. The message string is > also included in error reporting to > Microsoft. > > Use the FailFast method instead of the > Exit method to terminate your > application if the state of your > application is damaged beyond repair, > and executing your application's > try/finally blocks and finalizers will > corrupt program resources.

Solution 10 - C#

Simple answer Yes. But there are some "exceptions" to the rule.

Solution 11 - C#

The right answer is Yes.

Try to debug your program and put a break point and watch as control still hits the finally block.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRyan RodemoyerView Question on Stackoverflow
Solution 1 - C#kemiller2002View Answer on Stackoverflow
Solution 2 - C#msarchetView Answer on Stackoverflow
Solution 3 - C#Dirk VollmarView Answer on Stackoverflow
Solution 4 - C#Leniel MaccaferriView Answer on Stackoverflow
Solution 5 - C#Ian JacobsView Answer on Stackoverflow
Solution 6 - C#ZanoView Answer on Stackoverflow
Solution 7 - C#David CrowellView Answer on Stackoverflow
Solution 8 - C#Quintin RobinsonView Answer on Stackoverflow
Solution 9 - C#Johannes RudolphView Answer on Stackoverflow
Solution 10 - C#Jerod HoughtellingView Answer on Stackoverflow
Solution 11 - C#JonHView Answer on Stackoverflow