try-finally(C# 参考)try-finally (C# Reference)

通过使用 finally 块,可以清除 try 块中分配的任何资源,即使在 try 块中发生异常,也可以运行代码。By using a finally block, you can clean up any resources that are allocated in a try block, and you can run code even if an exception occurs in the try block. 通常情况下,finally 块的语句会在控件离开 try 语句时运行。Typically, the statements of a finally block run when control leaves a try statement. 正常执行中,执行 breakcontinuegotoreturn 语句,或者从 try 语句外传播异常都可能会导致发生控件转换。The transfer of control can occur as a result of normal execution, of execution of a break, continue, goto, or return statement, or of propagation of an exception out of the try statement.

已处理的异常中会保证运行相关联的 finally 块。Within a handled exception, the associated finally block is guaranteed to be run. 但是,如果异常未经处理,则 finally 块的执行将取决于异常解除操作的触发方式。However, if the exception is unhandled, execution of the finally block is dependent on how the exception unwind operation is triggered. 反过来,这又取决于你计算机的设置方式。That, in turn, is dependent on how your computer is set up.

通常情况下,当未经处理的异常终止应用程序时,finally 块是否运行已不重要。Usually, when an unhandled exception ends an application, whether or not the finally block is run is not important. 但是,如果 finally 块中的语句必须在这种情况下运行,则可以将 catch 块添加到 try-finally 语句,这是其中一种解决方法。However, if you have statements in a finally block that must be run even in that situation, one solution is to add a catch block to the try-finally statement. 另一种解决方法是,可以捕获可能在调用堆栈上方的 try``try- 语句的 finally 块中引发的异常。Alternatively, you can catch the exception that might be thrown in the try block of a try-finally statement higher up the call stack. 也就是说,可以通过以下几种方法来捕获异常:调用包含 try-finally 语句的方法、调用该方法或调用堆栈中的任何方法。That is, you can catch the exception in the method that calls the method that contains the try-finally statement, or in the method that calls that method, or in any method in the call stack. 如果未捕获异常,则 finally 块的执行取决于操作系统是否选择触发异常解除操作。If the exception is not caught, execution of the finally block depends on whether the operating system chooses to trigger an exception unwind operation.

示例Example

在以下示例中,无效的转换语句会导致 System.InvalidCastException 异常。In the following example, an invalid conversion statement causes a System.InvalidCastException exception. 异常未经处理。The exception is unhandled.

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 方法导致的异常会在比调用堆栈更远的方法中被捕获。In the following example, an exception from the TryCast method is caught in a method farther up the call stack.

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.
}

有关 finally 的详细信息,请参阅 try-catch-finallyFor more information about finally, see try-catch-finally.

C# 还包含 using 语句,它以简便语法为 IDisposable 对象提供类似的功能。C# also contains the using statement, which provides similar functionality for IDisposable objects in a convenient syntax.

C# 语言规范C# language specification

有关详细信息,请参阅 C# 语言规范中的 try 语句部分。For more information, see The try statement section of the C# language specification.

另请参阅See also