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.