Ausführen von Bereinigungscode mit finally

finally-Anweisungen sollen sicherstellen, dass die notwendige Bereinigung von Objekten, die externe Ressourcen enthalten, sofort erfolgen, auch wenn eine Ausnahme ausgelöst wird. Ein Beispiel für eine solche Bereinigung ist der Aufruf von Close auf einem FileStream sofort nach der Verwendung, anstatt abzuwarten, bis das Objekt durch die Common Language Runtime wie folgt speicherbereinigt wird:

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

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

    file.Close();
}

Beispiel

Um den vorherigen Code in eine try-catch-finally-Anweisung umzuwandeln, wird der Bereinigungscode wie folgt vom Arbeitscode getrennt.

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();
    }
}

Da eine Ausnahme zu einem beliebigen Zeitpunkt innerhalb des try-Blocks vor dem OpenWrite()-Aufruf auftreten oder der OpenWrite()-Aufruf selbst fehlschlagen kann, ist nicht garantiert, dass die Datei geöffnet ist, wenn wir versuchen, sie zu schließen. Der finally-Block fügt eine Überprüfung hinzu, um sicherzustellen, dass das FileStream-Objekt nicht null ist, bevor Sie die Close-Methode aufrufen. Ohne die null-Überprüfung kann der finally-Block eine eigene NullReferenceException-Ausnahme auslösen. Das Auslösen von Ausnahmen in finally-Blöcken sollte allerdings nach Möglichkeit vermieden werden.

Auch Datenbankverbindungen können mit einem finally-Block geschlossen werden. Da die Anzahl der zulässigen Verbindungen mit einem Datenbankserver manchmal begrenzt ist, sollten Sie Datenbankverbindungen so schnell wie möglich schließen. Wenn eine Ausnahme ausgelöst wird, bevor Sie die Verbindung beenden können, ist es besser, den finally-Block zu verwenden, anstatt auf due automatische Speicherbereinigung zu warten.

Siehe auch