![](/img/trans.png)
[英]What's the use of a finally block preceded by a catch-all catch block, in C#?
[英]In .NET, what if something fails in the catch block, will finally always get called?
在 try/catch/finally 块中,例如:
try
{
}
catch()
{
// code fails here
}
finally
{
}
那么如果catch块中有异常,最终总是会被调用吗?
如果没有 finally,catch 块之后的代码会运行吗?
假设进程不会突然终止(当然也不会挂起),finally 块将始终被执行。
如果没有 finally 块,catch 块中的异常将被抛出堆栈。 请注意,最初导致 catch 块执行的原始异常将被有效地丢失。
堆栈溢出异常
正如 Jared 所指出的,堆栈溢出将导致 finally 块不被执行。 我相信这会突然终止程序,但我可能是错的。 这是示例代码:
using System;
public class Test
{
static void Main()
{
// Give the stack something to munch on
int x = 10;
try
{
Main();
Console.WriteLine(x);
}
finally
{
Console.WriteLine("Finally");
}
}
}
结果:
进程因 StackOverflowException 而终止。
finally 块将始终被执行。 如果您排除 finally 块,并且在 catch 块内发生异常,则 catch 块之后不会执行任何代码,因为本质上您的 catch 块将失败并自身生成未处理的异常。
是的,finally 将永远运行
不,catch 块之后的代码将不会运行。
即使使用 finally 块,finally 块之后的任何代码都不会运行。
如果 catch 块中有异常,finally 会执行,但是会抛出一个新的异常。 发生异常的 catch 块不会捕获异常,它会继续向上堆栈。
经验教训:如果你能帮助它,不要在 catch 块中做可以抛出的东西; 如果必须,请嵌套一个 try/catch 块。
try
{
}
catch()
{
try
{
// code fails here
}
catch
{
// handle that. Or not.
}
}
finally
{
}
finally 块将始终被执行。 来自MSDN :
finally 块对于清理在 try 块中分配的任何资源以及运行任何必须执行的代码(即使存在异常)也很有用。 不管 try 块如何退出,控制总是传递给 finally 块。
catch 用于处理语句块中发生的异常,而 finally 用于保证语句块的执行,而不管前面的 try 块如何退出。
顺便说一句,这是您可以通过编写一些代码、编译它并查看执行它时发生的情况来轻松测试自己的问题类型。
class Program {
static void Main(string[] args) {
try {
Console.WriteLine("Trying!");
throw new Exception();
}
catch (Exception e) {
Console.WriteLine("Catching {0}!", e.Message);
throw new Exception();
}
finally {
Console.WriteLine("Finally!");
}
}
}
这输出:
Trying!
Catching Exception of type 'System.Exception' was thrown.!
Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at TestFinally.Program.Main(String[] args) in C:\Documents and Settings\Me\My
Documents\Visual Studio 2008\Projects\TestFinally\TestFinally\Program.cs:line 15
Finally!
Press any key to continue. . .
只是想添加我知道的不允许 finally 和任何其他代码块执行的情况:
如果 catch 块中发生异常,finally 中的所有代码仍然会被执行。 如果堆栈中有更高的异常处理程序(例如此函数的调用者),它将捕获此异常。 否则会导致未处理的异常并关闭您的应用程序。
catch 块中异常点之后的代码不会被调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.