try-finally (Referencia de C#)

Mediante el uso de un bloque finally, puede limpiar todos los recursos asignados en un bloque try y ejecutar código incluso si se produce una excepción en el bloque try. Normalmente, las instrucciones de un bloque finally se ejecutan cuando el control abandona una instrucción try. La transferencia de control se puede producir como resultado de la ejecución normal, de la ejecución de una instrucción break, continue, goto o return, o de la propagación de una excepción fuera de la instrucción try.

Dentro de una excepción controlada, se garantiza la ejecución del bloque finally asociado. Pero en el caso de una excepción no controlada, la ejecución del bloque finally depende de la manera en que se desencadene la operación de desenredo de la excepción. Esto, a su vez, depende de cómo esté configurado el equipo. Los únicos casos en los que no se ejecutan las cláusulas finally implican que un programa se detenga inmediatamente. Un ejemplo de esto sería cuando se produce InvalidProgramException debido a que las instrucciones IL están dañadas. En la mayoría de los sistemas operativos, la limpieza de recursos razonable tendrá lugar como parte de la detención y descarga del proceso.

Normalmente, cuando una excepción no controlada finaliza una aplicación, no es importante si el bloque finally se ejecuta o no. Pero si tiene instrucciones en un bloque finally que debe ejecutarse incluso en esa situación, una solución es agregar un bloque catch a la instrucción try-finally. Como alternativa, puede capturar la excepción que se podría producir en el bloque try de una instrucción try-finally más arriba en la pila de llamadas. Es decir, puede capturar la excepción en el método que llama al método que contiene la instrucción try-finally, en el método que llama a ese método o en cualquier método en la pila de llamadas. Si no se captura la excepción, la ejecución del bloque finally depende de si el sistema operativo decide desencadenar una operación de desenredo de la excepción.

Ejemplo

En el ejemplo siguiente, una instrucción de conversión no válida provoca una excepción System.InvalidCastException. Se trata de una excepción no controlada.

public class ThrowTestA
{
    public static void Main()
    {
        int i = 123;
        string s = "Some string";
        object obj = s;

        try
        {
            // Invalid conversion; obj contains a string, not a numeric type.
            i = (int)obj;

            // The following statement is not run.
            Console.WriteLine("WriteLine at the end of the try block.");
        }
        finally
        {
            // To run the program in Visual Studio, type CTRL+F5. Then
            // click Cancel in the error dialog.
            Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                "error depends on how the exception unwind operation is triggered.");
            Console.WriteLine("i = {0}", i);
        }
    }
    // Output:
    // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
    //
    // Execution of the finally block after an unhandled
    // error depends on how the exception unwind operation is triggered.
    // i = 123
}

En el ejemplo siguiente, se captura una excepción del método TryCast en un método más arriba en la pila de llamadas.

public class ThrowTestB
{
    public static void Main()
    {
        try
        {
            // TryCast produces an unhandled exception.
            TryCast();
        }
        catch (Exception ex)
        {
            // Catch the exception that is unhandled in TryCast.
            Console.WriteLine
                ("Catching the {0} exception triggers the finally block.",
                ex.GetType());

            // Restore the original unhandled exception. You might not
            // know what exception to expect, or how to handle it, so pass
            // it on.
            throw;
        }
    }

    static void TryCast()
    {
        int i = 123;
        string s = "Some string";
        object obj = s;

        try
        {
            // Invalid conversion; obj contains a string, not a numeric type.
            i = (int)obj;

            // The following statement is not run.
            Console.WriteLine("WriteLine at the end of the try block.");
        }
        finally
        {
            // Report that the finally block is run, and show that the value of
            // i has not been changed.
            Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
        }
    }
    // Output:
    // In the finally block in TryCast, i = 123.

    // Catching the System.InvalidCastException exception triggers the finally block.

    // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}

Para obtener más información sobre finally, vea try-catch-finally.

C# también contiene la instrucción using, que proporciona una función similar para objetos IDisposable en una sintaxis adecuada.

especificación del lenguaje C#

Para obtener más información, vea la sección sobre la instrucción try de la Especificación del lenguaje C#.

Vea también