Condividi tramite


Come eseguire codice di pulitura mediante finally

Lo scopo di un'istruzione finally consiste nel garantire che la pulizia necessaria di oggetti, in genere oggetti che contengono risorse esterne, venga eseguita immediatamente, anche se viene generata un'eccezione. Un esempio di questo tipo di pulizia è la chiamata di Close in un oggetto FileStream immediatamente dopo l'uso, invece di aspettare che l'oggetto venga sottoposto a Garbage Collection da Common Language Runtime, come illustrato di seguito:

static void CodeWithoutCleanup()
{
    FileStream? file = null;
    FileInfo fileInfo = new FileInfo("./file.txt");

    file = fileInfo.OpenWrite();
    file.WriteByte(0xF);

    file.Close();
}

Esempio

Per trasformare il codice precedente in un'istruzione try-catch-finally, il codice di pulitura viene separato dal codice di lavoro, come indicato di seguito.

static void CodeWithCleanup()
{
    FileStream? file = null;
    FileInfo? fileInfo = null;

    try
    {
        fileInfo = new FileInfo("./file.txt");

        file = fileInfo.OpenWrite();
        file.WriteByte(0xF);
    }
    catch (UnauthorizedAccessException e)
    {
        Console.WriteLine(e.Message);
    }
    finally
    {
        file?.Close();
    }
}

Poiché un'eccezione può verificarsi in qualsiasi momento all'interno del blocco try prima della chiamata OpenWrite(), o della stessa chiamata OpenWrite(), potrebbe non riuscire, non è garantito che il file sia aperto quando si tenta di chiuderlo. Il blocco finally aggiunge un controllo per verificare che l'oggetto FileStream non sia null prima di chiamare il metodo Close. Senza il controllo di null, il blocco finally potrebbe generare la propria eccezione NullReferenceException, ma la generazione di eccezioni nei blocchi finally deve essere evitata, se possibile.

Una connessione di database è un altro elemento ideale da chiudere in un blocco finally. Poiché il numero di connessioni consentite in un server di database è talvolta limitato, è necessario chiudere le connessioni di database il più rapidamente possibile. Se viene generata un'eccezione prima che la connessione venga chiusa, l'uso del blocco finally è preferibile rispetto all'attesa di Garbage Collection.

Vedi anche