try-finally (Referência de C#)

Usando um bloco finally, você pode limpar todos os recursos alocados em um bloco try e pode executar código mesmo se uma exceção ocorrer no bloco try. Normalmente, as instruções de um bloco finally são executadas quando o controle deixa uma instrução try. A transferência de controle pode ocorrer como resultado da execução normal, da execução de uma instrução break, continue, goto ou return, ou da propagação de uma exceção para fora da instrução try.

Dentro de uma exceção tratada, é garantido que o bloco finally será executado. No entanto, se a exceção não for tratada, a execução do bloco finally depende de como a operação de desenrolamento da exceção é disparada. Isso, por sua vez, depende da configuração do seu computador. Os únicos casos em que as finally cláusulas não são executadas envolvem um programa que está sendo imediatamente interrompido. Um exemplo disso seria quando InvalidProgramException é gerado devido às instruções Il sendo corrompidas. Na maioria dos sistemas operacionais, a limpeza de recursos razoáveis ocorrerá como parte da interrupção e descarregamento do processo.

Normalmente, quando uma exceção sem tratamento encerra um aplicativo, não é importante se o bloco finally é executado. No entanto, se você tiver instruções em um bloco finally que devem ser executadas mesmo nesse caso, uma solução é adicionar um bloco catch à instrução try-finally. Como alternativa, você pode detectar a exceção que pode ser gerada no bloco try de uma instrução try-finally em posição superior na pilha de chamadas. Ou seja, você pode detectar a exceção no método que chama o método que contém a instrução try-finally ou no método que chama esse método ou em qualquer método na pilha de chamadas. Se a exceção não for detectada, a execução do bloco finally dependerá do sistema operacional escolher disparar uma operação de desenrolamento de exceção.

Exemplo

No exemplo a seguir, uma instrução de conversão inválida causa uma exceção System.InvalidCastException. A exceção não é tratada.

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
}

No exemplo a seguir, uma exceção do método TryCast ocorre em um método mais para cima na pilha de chamadas.

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 obter mais informações sobre finally, consulte try-catch-finally.

C# também contém a instrução using, que fornece uma funcionalidade semelhante para objetos IDisposable em uma sintaxe conveniente.

Especificação da linguagem C#

Para obter mais informações, confira a seção A instrução try da Especificação da linguagem C#.

Confira também