try...finally (Riferimenti per C#)

Usando un blocco finally, è possibile eliminare le risorse allocate in un blocco try ed è possibile eseguire codice anche se viene generata un'eccezione di blocco try. In genere, le istruzioni di un blocco finally vengono eseguite quando il controllo lascia un'istruzione try. Il trasferimento del controllo può verificarsi come risultato dell'esecuzione normale, dell'esecuzione di un'istruzione break, continue, goto o return o della propagazione di un'eccezione dell'istruzione try.

All'interno di un'eccezione gestita, l'esecuzione del blocco finally associato è garantita. Tuttavia, se l'eccezione non è gestita, l'esecuzione del blocco finally dipende da come viene attivata l'operazione di rimozione dell'eccezione. Ciò, a sua volta, dipende da come viene configurato il computer. Gli unici casi in finally cui le clausole non vengono eseguite comportano l'arresto immediato di un programma. Un esempio è quando viene generata a causa del danneggiamento delle InvalidProgramException istruzioni IL. Nella maggior parte dei sistemi operativi verrà eseguita una pulizia delle risorse ragionevole come parte dell'arresto e dello scaricamento del processo.

In genere, quando un'eccezione non gestita termina un'applicazione non è importante sapere se il blocco finally è in esecuzione. Tuttavia, se si dispone di istruzioni in un blocco finally che deve essere eseguito anche in questo caso, una soluzione consiste nell'aggiungere un blocco catch all'istruzione try-finally. In alternativa, è possibile intercettare l'eccezione che potrebbe essere generata nel blocco try di un'istruzione try-finally in alto nello stack di chiamate. Vale a dire, è possibile intercettare l'eccezione nel metodo che chiama il metodo che contiene l'istruzione try-finally, nel metodo che chiama questo metodo o in qualsiasi metodo nello stack di chiamate. Se non viene rilevata l'eccezione, l'esecuzione del blocco finally varia a seconda che il sistema operativo scelga di generare un'operazione di rimozione dell'eccezione o meno.

Esempio

Nell'esempio seguente un'istruzione di conversione non valida causa un'eccezione System.InvalidCastException. L'eccezione viene non è gestita.

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
}

Nell'esempio seguente viene intercettata un'eccezione del metodo TryCast in un metodo nella parte più in alto dello stack di chiamate.

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

Per altre informazioni su finally, vedere try-catch-finally.

C# contiene anche l'istruzione using, che fornisce funzionalità simili per gli oggetti IDisposable con una sintassi comoda.

Specifiche del linguaggio C#

Per altre informazioni, vedere la sezione Istruzione try della specifica del linguaggio C#.

Vedi anche