Search code examples
c#.netexceptionidisposableusing-statement

IDisposable.Dispose is never called after exception in using block


I understand from many sources like this and this that the Dispose method of an IDisposable will always be called if an exception is thrown in a Using block. So then I have this code:

static class MainEntryPoint
{
    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;

        using (var x = new Disposable())
        {
            throw new Exception("asdfsdf");
        }
    }

    private static void HandleUnhandledException(Object sender, System.UnhandledExceptionEventArgs e)
    {
        Environment.Exit(0);
    }
}

class Disposable : IDisposable
{
    public void Dispose()
    {
        System.Diagnostics.Debug.Print("I am disposed");
    }
}

It exits the application when an un-handled exception is thrown. The Dispose method is never called. Why?


Solution

  • Environment.Exit will terminate the program

    If Exit is called from a try or catch block, the code in any finally block does not execute. If the return statement is used, the code in the finally block does execute.

    using (var x = new Disposable())
    {
        throw new Exception("asdfsdf");
    }
    

    will be converted to

    Disposable x = new Disposable();
    try
    {
        throw new Exception("asdfsdf");
    }
    finally
    {
        if (x != null)
            x.Dispose();
    }