Como executar o código de limpeza usando finalmente
O objetivo de uma finally
instrução é garantir que a limpeza necessária de objetos, geralmente objetos que estão contendo recursos externos, ocorra imediatamente, mesmo que uma exceção seja lançada. Um exemplo dessa limpeza é chamar Close um FileStream imediatamente após o uso, em vez de esperar que o objeto seja coletado pelo common language runtime, da seguinte forma:
static void CodeWithoutCleanup()
{
FileStream? file = null;
FileInfo fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
file.Close();
}
Exemplo
Para transformar o código anterior em uma try-catch-finally
instrução, o código de limpeza é separado do código de trabalho, da seguinte maneira.
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();
}
}
Como uma exceção pode ocorrer a qualquer momento dentro do bloco antes da try
OpenWrite()
chamada, ou a OpenWrite()
chamada em si pode falhar, não temos garantia de que o arquivo esteja aberto quando tentamos fechá-lo. O finally
bloco adiciona uma verificação para certificar-se de que o FileStream objeto não null
está antes de chamar o Close método. Sem o null
cheque, o bloco poderia lançar o finally
seu próprio NullReferenceException, mas lançar exceções em finally
blocos deve ser evitado se for possível.
Uma conexão de banco de dados é outro bom candidato para ser fechada em um finally
bloco. Como o número de conexões permitidas a um servidor de banco de dados às vezes é limitado, você deve fechar as conexões de banco de dados o mais rápido possível. Se uma exceção for lançada antes que você possa fechar sua conexão, usar o finally
bloco é melhor do que esperar pela coleta de lixo.