Используя блок finally
, вы можете очистить любые ресурсы, выделенные в блоке try
, и запустить код, даже если в блоке try
возникает исключительная ситуация. Обычно операторы блока finally
выполняются, когда элемент управления покидает оператор try. Передача управления может происходить в результате нормального выполнения, выполнения оператора break, continue, goto, or return
или распространения исключения из оператора try
.
Внутри обработанного исключения гарантированно будет работать связанный блок finally
. Однако, если исключение не обработано, выполнение блока finally
зависит от того, как запущена операция размотки исключения. Это, в свою очередь, зависит от того, как настроен ваш компьютер. Для получения дополнительной информации см. Обработка необработанных исключений в CLR .
Обычно, когда необработанное исключение завершает приложение, неважно, запущен или нет блок finally
. Однако, если у вас есть операторы в блоке finally
, которые должны выполняться даже в такой ситуации, одним из решений является добавление блока catch
в оператор try-finally
. Кроме того, вы можете перехватить исключение, которое может быть выброшено в блоке try
оператора try-finally
выше стека вызовов. То есть вы можете перехватить исключение в методе, который вызывает метод, содержащий оператор try-finally
, или в методе, который вызывает этот метод, или в любом методе в стеке вызовов. Если исключение не перехвачено, выполнение блока finally
зависит от того, выберет ли операционная система запуск операции исключения.
public class ThrowTestA
{
static void Main()
{
int i = 123;
string s = "Some string";
object obj = s;
try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;
// The following statement is not run.
Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// To run the program in Visual Studio, type CTRL+F5. Then
// click Cancel in the error dialog.
Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
"error depends on how the exception unwind operation is triggered.");
Console.WriteLine("i = {0}", i);
}
}
// Output:
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
//
// Execution of the finally block after an unhandled
// error depends on how the exception unwind operation is triggered.
// i = 123
}
В следующем примере исключение из метода TryCast перехватывается в методе, расположенном дальше по стеку вызовов.
C #
public class ThrowTestB
{
static void Main()
{
try
{
// TryCast produces an unhandled exception.
TryCast();
}
catch (Exception ex)
{
// Catch the exception that is unhandled in TryCast.
Console.WriteLine
("Catching the {0} exception triggers the finally block.",
ex.GetType());
// Restore the original unhandled exception. You might not
// know what exception to expect, or how to handle it, so pass
// it on.
throw;
}
}
public static void TryCast()
{
int i = 123;
string s = "Some string";
object obj = s;
try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;
// The following statement is not run.
Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// Report that the finally block is run, and show that the value of
// i has not been changed.
Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
}
}
// Output:
// In the finally block in TryCast, i = 123.
// Catching the System.InvalidCastException exception triggers the finally block.
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}