Wykonywanie czyszczenia kodu za pomocą instrukcji finally
Celem instrukcji finally
jest zapewnienie niezbędnego czyszczenia obiektów, zwykle obiektów, które przechowują zasoby zewnętrzne, występuje natychmiast, nawet jeśli zostanie zgłoszony wyjątek. Jednym z przykładów takiego czyszczenia jest wywołanie Close metody bezpośrednio po użyciu zamiast oczekiwania na FileStream odśmiecanie pamięci obiektu przez środowisko uruchomieniowe języka wspólnego w następujący sposób:
static void CodeWithoutCleanup()
{
FileStream? file = null;
FileInfo fileInfo = new FileInfo("./file.txt");
file = fileInfo.OpenWrite();
file.WriteByte(0xF);
file.Close();
}
Przykład
Aby przekształcić poprzedni kod w instrukcję try-catch-finally
, kod oczyszczania jest oddzielony od działającego kodu w następujący sposób.
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();
}
}
Ponieważ wyjątek może wystąpić w dowolnym momencie w bloku try
przed OpenWrite()
wywołaniem lub OpenWrite()
wywołanie może zakończyć się niepowodzeniem, nie mamy gwarancji, że plik jest otwarty podczas próby jego zamknięcia. Blok finally
dodaje sprawdzanie, aby upewnić się, że FileStream obiekt nie null
jest przed wywołaniem Close metody. Bez sprawdzania null
finally
blok może zgłaszać własne NullReferenceException, ale należy unikać zgłaszania wyjątków w blokach, finally
jeśli jest to możliwe.
Połączenie z bazą danych jest kolejnym dobrym kandydatem finally
do zamknięcia w bloku. Ponieważ liczba połączeń dozwolonych na serwerze bazy danych jest czasami ograniczona, należy jak najszybciej zamknąć połączenia z bazą danych. Jeśli wyjątek zostanie zgłoszony przed zamknięciem połączenia, użycie finally
bloku jest lepsze niż oczekiwanie na odzyskiwanie pamięci.