Cómo: Ejecutar código de limpieza mediante finally (Guía de programación de C#)

Actualización: noviembre 2007

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

static void CodeWithoutCleanup()
{
    System.IO.FileStream file = null;
    System.IO.FileInfo fileInfo = new System.IO.FileInfo("C:\\file.txt");

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

    file.Close();
}

Ejemplo

Para convertir el código anterior en una instrucción try-catch-finally, el código de limpieza está separado del código activo como se muestra a continuación.

static void CodeWithCleanup()
{
    System.IO.FileStream file = null;
    System.IO.FileInfo fileInfo = null;

    try
    {
        fileInfo = new System.IO.FileInfo("C:\\file.txt");

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

Dado que una excepción puede producirse dentro del bloque try en cualquier momento antes de llamar a OpenWrite() o que puede producirse un error en la propia llamada a OpenWrite(), no hay garantías de que el archivo esté abierto al intentar cerrarlo. El bloque finally agrega una comprobación que garantiza que el objeto FileStream no es null antes de llamar al método Close. Sin la comprobación de null, el bloque finally podría iniciar su propia excepción NullReferenceException, pero debería evitarse en lo posible producir excepciones en los bloques finally.

Una conexión de base de datos también es un elemento que debería cerrarse en un bloque finally. Dado que el número de conexiones permitidas a un servidor de base de datos en ocasiones es limitado, las conexiones de base de datos deben cerrarse tan rápido como sea posible. Si se produjera una excepción antes de poder cerrar la conexión, se trataría de otro caso en el que sería preferible utilizar el bloque finally a esperar a la recolección de elementos no utilizados.

Vea también

Conceptos

Guía de programación de C#

Referencia

Excepciones y control de excepciones (Guía de programación de C#)

Control de excepciones (Guía de programación de C#)

using (Instrucción, Referencia de C#)

try-catch (Referencia de C#)

try-finally (Referencia de C#)

try-catch-finally (Referencia de C#)