Share via


Procedimiento para ejecutar código de limpieza mediante finally

El propósito de una instrucción finally es asegurarse de que la limpieza necesaria de los objetos, por lo general objetos que contienen recursos externos, se produzca inmediatamente, incluso si se produce una excepción. Un ejemplo de esta limpieza es llamar a Close en un FileStream inmediatamente después de su uso en lugar de esperar a que el objeto sea recolectado por el Common Language Runtime, de esta forma:

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

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

    file.Close();
}

Ejemplo

Para activar el código anterior en una instrucción try-catch-finally, el código de limpieza se separa del código de trabajo, de esta forma.

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

Dado que una excepción puede producirse en cualquier momento dentro del bloque try antes de la llamada a OpenWrite(), o que podría producirse un error en la propia llamada a OpenWrite(), no se garantiza que el archivo esté abierto cuando se intente cerrar. El bloque finally agrega una comprobación para asegurarse de que el objeto FileStream no sea null antes de que se pueda llamar al método Close. Sin la comprobación null, el bloque finally podría iniciar su propia excepción NullReferenceException, pero debería evitarse generar excepciones en bloques finally, si es posible.

Una conexión de base de datos es otra buena candidata para cerrarse en un bloque finally. Dado que a veces se limita el número de conexiones permitido en un servidor de base de datos, se deben cerrar las conexiones de base de datos tan pronto como sea posible. Si se produce una excepción antes de poder cerrar la conexión, es mejor usar el bloque finally que esperar a la recolección de elementos no utilizados.

Consulte también