[ACCEPTED]-Conditions when finally does not execute in a .net try..finally block-exception-handling

Accepted answer
Score: 55

Two possibilities:

The finally block will 5 not be executed when there's a StackOverflowException since there's 4 no room on the stack to even execute any 3 more code. It will also not be called when 2 there's an ExecutionEngineException, which may arise from a call 1 to Environment.FailFast().

Score: 15

Unless the CLR blows up and goes down with 4 an ExecutingEngineException (I've seen a 3 few in the .net 1.1 days with just the right 2 amount of COM Interop :) .. I think finally 1 should always execute.

Score: 7

You can get a situation where the code in 8 the try block causes a SecurityException 7 to be thrown before the try block entered 6 (instead the exception is thrown when the 5 containing method is called (see http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx)), in 4 this situation you never even enter the 3 try block so the code in the finally block 2 is never called.

Other possibilities include 1 StackOverflowException, and ExecutingEngineException.

Score: 4

Finally block on background thread may not execute. However, It 3 depends upon the completed execution of 2 main foreground thread which terminates background thread operation even before 1 the complete execution of background thread.

class Program
{

    static void Main(string[] args)
    {
        Program prgm = new Program();
        Thread backgroundThread = new Thread(prgm.CheckBgThread);
        backgroundThread.IsBackground = true;
        backgroundThread.Start();
        Console.WriteLine("Closing the program....");
    }

    void CheckBgThread()
    {
        try
        {
            Console.WriteLine("Doing some work...");
            Thread.Sleep(500);
        }
        finally
        {
            Console.WriteLine("This should be always executed");
        }
    }
}
Score: 2

There is also Application.Exit method.

0

Score: 1

Since async/await, there is another way 2 a finally might get ignored that I haven't 1 seen mentioned in other answers:

static class Program
{
    [STAThread]
    static void Main()
    {
        async void ThreadExecutionAsync()
        {
            try
            {
                SynchronizationContext.SetSynchronizationContext(
                    new WindowsFormsSynchronizationContext());

                await Task.Yield(); // Yield to the context

                // The WindowsFormsSynchronizationContext will schedule the continuation
                // on the main thread, so the current thread will die
                // and we will never get here...
                Debugger.Break();
            }
            finally
            {
                // Will never get here either...
                Debugger.Break();
            }
        }

        var thread = new Thread(ThreadExecutionAsync);
        thread.Start();

        Application.Run();
    }
}
Score: 0

Neither code which follows a finally block, nor 13 code in outer scopes, will execute without 12 the finally block having been started first 11 (an exception within the finally block may 10 cause it to exit prematurely, in which case 9 execution will jump out from the finalizer 8 to an outer scope). If code prior to the 7 finally block gets stuck in an endless loop 6 or a method that never exits, or if the 5 execution context is destroyed altogether, the 4 finally block will not execute.

Note that 3 it is proper to rely upon finally blocks, unlike 2 "Finalize" methods (or C# "destructors") which 1 should not properly be relied upon.

More Related questions