c# - 如果我从 C# 中的 try/finally block 中返回,finally 中的代码是否总是运行?

标签 c# try-catch-finally

根据一些初步测试,它似乎确实如此,但我想知道的是它是否保证返回,或者在某些情况下是否不能返回?这对我的应用程序至关重要,但我还没有找到它不会返回的用例。
我想获得有关该主题的专业知识。

最佳答案

其他答案中有许多不准确之处。

当控制权正常离开 try block 时,控制权被传递到 finally block ——也就是说,通过 return、goto、break、continue 或简单地从末尾掉下来。当控制权离开 try block 时,控制权将通过已被封闭的 catch block 捕获的异常传递给 finally block

在任何其他情况下,都不能保证 finally block 中的代码将被调用。特别是:

  • 如果 try block 代码进入无限循环,或者线程被卡住且从未解冻,则永远不会调用 finally block 代码。

  • 如果进程在调试器中暂停,然后被主动终止,则永远不会调用 finally block 。如果进程执行快速失败,则永远不会调用 finally block 。

  • 如果电源线从墙上拔出,则永远不会调用 finally block 。

  • 如果在没有相应的 catch block 的情况下抛出异常,那么 finally block 是否运行是运行时的实现细节。当存在未捕获的异常时,运行时可以选择任何行为。 “不运行 finally block ”和“执行 finally block ”都是“任何行为”的示例,因此可以选择其中一个。通常,运行时所做的是在 finally block 运行之前询问用户是否要附加调试器;如果用户拒绝,则 finally block 运行。但同样:不需要运行时来执行此操作。它可能很快就会失败。

你不能依赖 finally block 总是被调用。如果你需要一个关于代码执行的强有力的保证,那么你不应该写一个 try-finally,你应该写一个 constrained execution region .正确编写 CER 是 C# 编程中最困难的任务之一,因此在尝试编写代码之前请仔细阅读文档。

顺便说一句,关于 finally-blocked goto 的一个“有趣的事实”是:

try { goto X; } finally { throw y; } 
X : Console.WriteLine("X");

X 是可到达的 goto 所指向的不可到达的标签!所以下次你在聚会上时,你可以说“嘿大家,谁能制作一个 C# 程序,它有一个无法访问的标签,由一个可访问的 goto 定位?”你会看到聚会上谁阅读了可达性规范,谁还没有阅读!

关于c# - 如果我从 C# 中的 try/finally block 中返回,finally 中的代码是否总是运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10255774/

相关文章:

Python 尝试除了最后

iphone - @try - Objective-C 中的 catch block

java - 我们可以在 finally block 中使用 "return"

c# - DataGridTextColumn 可见性绑定(bind)

c# - 如何在 C# 中制作一个适用于多个控件的事件处理程序?

c# - 如何最小化 Entity Framework SaveChangesAsync?

java - catch是java中的一个方法吗?

C# - 使用扩展方法排序

c# - 具有多个类类型的单个组合 C# 列表

java - 最后尝试关闭多个流