Конструкция try-catch-finally
в C# предоставляет механизм для обработки исключений и управления ресурсами:
try
{
// Код, который может вызвать исключение
FileStream file = File.Open("data.txt", FileMode.Open);
// Работа с файлом
}
catch (FileNotFoundException ex)
{
Console.WriteLine($"Файл не найден: {ex.FileName}");
}
catch (IOException ex)
{
Console.WriteLine($"Ошибка ввода-вывода: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Неизвестная ошибка: {ex.Message}");
throw; // Повторное возбуждение исключения
}
finally
{
// Код освобождения ресурсов
file?.Close();
Console.WriteLine("Операция завершена");
}
Хотя блок finally предназначен для гарантированного выполнения, есть редкие ситуации, когда он не сработает:
try
{
Environment.FailFast("Критическая ошибка");
}
finally
{
// Этот код не выполнится
Console.WriteLine("Finally");
}
try
{
while (true) { } // Бесконечный цикл
}
finally
{
// Не достигнет этого места
}
Выключение питания или аппаратный сбой
StackOverflowException (в некоторых версиях .NET)
OutOfMemoryException (когда нет памяти для выполнения finally)
FileStream file = null;
try
{
file = File.Open("data.txt", FileMode.Open);
// Работа с файлом
}
finally
{
file?.Dispose(); // Гарантированное освобождение
}
using (var file = File.Open("data.txt", FileMode.Open))
{
// Работа с файлом
} // Dispose() вызовется автоматически
int BadPractice()
{
try
{
return 1;
}
finally
{
return 2; // Это значение будет возвращено!
}
}
Обработка подключения к базе данных:
SqlConnection connection = null;
try
{
connection = new SqlConnection(connectionString);
connection.Open();
// Выполнение запросов
using (var command = new SqlCommand("SELECT ...", connection))
{
// Работа с данными
}
}
catch (SqlException ex)
{
_logger.Error("Ошибка БД", ex);
throw new DataAccessException("Ошибка доступа к данным", ex);
}
finally
{
// Гарантированное закрытие подключения
if (connection?.State != ConnectionState.Closed)
{
connection?.Close();
}
}
try-catch-finally - основа обработки ошибок в C#
Finally выполняется почти всегда, кроме:
Основные применения:
Лучшие альтернативы:
Правильное использование try-catch-finally - признак зрелого разработчика, пишущего надежный и устойчивый к ошибкам код.