对于finally块,我有些困惑。我知道无论是否有异常,都可以执行finally块。
我有2种情况:-
1)如果try块中有异常,而我没有为此try块编写任何catch块,但是我有一个finally块,那么finally块将被执行吗?如果未处理异常,finally会阻止执行吗?
下面是示例代码:-
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
//catch (Exception ex)
//{
// int divide = 12 / x;
// Console.WriteLine(ex.Message);
//}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
2)如果catch块中有异常,是否会执行finally块? 下面是示例代码:-
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
int divide = 12 / x; // this will throw exception in catch block
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
我已经尝试过这些代码,但看不到finally块被执行。 请解释一下为什么finally代码块不执行。
答案 0 :(得分:2)
实际上,try-catch-finally
块的作用如下:
放置潜在问题代码的地方。如果生成异常,则会引发异常。
catch是唯一会被捕获 的异常的块。由此得名。因此,当引发异常时,如果要确保不使程序“挂起”,则必须catch
进行异常。
进行清理。举例来说,如果您的try
块中有某个数组,并且想在发生异常的情况下清理它,那么这里就是这样做的地方。
在已处理的异常内,可以保证关联的finally块可以运行。 但是,如果未处理异常,则finally块的执行取决于异常展开操作的触发方式。而这又取决于计算机的设置方式。
意思是,如果您没有捕获到异常,则取决于情况是否运行finally
。
因此,考虑到这一点,让我们看一下您的第一个代码块。
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
您正在尝试除以零,这会产生异常。但是没有被“捕获”的地方,因此程序挂起:
因此,如果您在此处添加一个catch
块,现在它将使航行顺畅,也可以转到您的finally
。
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine("Oops. Division by Zero.");
}
finally
{
Console.WriteLine("I am finally block");
}
现在,让我们来看第二个代码段。我将做一个小的修改并翻转catch
中两行代码的顺序。
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
int divide = 12 / x;
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
现在,catch
块捕获到第一个非法分割所引发的异常并打印一条消息。但是catch
内还有第二个非法分区,并且没有抛出异常的陷阱,因此程序挂起。
因此,如果您将其修改为在第一个try-catch
中有第二个catch
,如下所示:
static void Main(string[] args)
{
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
try
{
Console.WriteLine(ex.Message);
int divide = 12 / x;
}
catch (Exception ex2)
{
Console.WriteLine(ex2.Message);
}
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
}
现在它将捕获这两个异常,您很好。
所以想法是,如果您有try
,则应该尝试拥有catch
,除非您可以证明为什么不想要一个。
答案 1 :(得分:0)
遵循article MSDN
在已处理的异常内,可以保证关联的finally块 要运行
这意味着对于try catch finally
,必须执行finally
中的代码。
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
输出:
Attempted to divide by zero. // catch Console.WriteLine(ex.Message);
I am finally block // finally
如果未处理异常,则执行finally块 取决于如何触发异常展开操作。在 取决于您计算机的设置方式。
这意味着它取决于抛出的finally
代码是否执行。如果StackOverflowException
或一个异常ExecutionEngineException
(可能调用该异常以调用Environment.FailFast()或Environment.Exit()),则您的finally
代码将不会执行,因为您的应用程序已关闭以前。
在您的情况2中,DivideByZeroException
中的catch
或情况1中的try
中有一个例外finally
,将被执行。 / p>
int x = 0;
try
{
int divide = 12 / x;
}
catch (Exception ex)
{
int divide = 12 / x; // no handled
Console.WriteLine(ex.Message);
}
finally
{
Console.WriteLine("I am finally block");
}
Console.ReadLine();
输出:
I am finally block // finally
Run-time exception (line 16): Attempted to divide by zero. // exception non handled catch by the level plus high that cause crashing the application