可能重复:
Conditions when finally does not execute in a .net try..finally block
In C# will the finally block be executed in a try, catch, finally if an unhandled exception is thrown?
http://en.wikipedia.org/wiki/Comparison_of_C_Sharp_and_Java#Finally_Blocks_and_Uncaught_Exceptions表示finally
块并不总是运行。那是对的,对吧?
CLI的ECMA标准(C#从中派生其异常特性)指出异常是在堆栈的两遍搜索中处理的。[13]第一遍尝试找到匹配的catch块,如果没有找到则终止程序。只有找到匹配的catch块才会执行第二次执行,这将运行插入的finally块。这允许在没有程序状态首先被finally块修改的情况下诊断问题;它还消除了当程序处于未知状态时(例如外部数据损坏或抛出更多异常),最终块可能产生不良副作用的风险。
但是,我最终不需要捕获:
static void Main()
{
try { throw new Exception(); }
finally
{
Console.WriteLine("1");
}
}
答案 0 :(得分:7)
我注意到没有人真正回答过你的问题,“这个文字是否正确?”
不,这是不正确的,因为它省略了重要的一点。
未能引用的CLI规范的相关部分是第I部分的第12.4.2节,其中规定:
终于处理程序......应该是 块退出时执行, 无论是否发生 正常的控制流程或未处理的 异常。
现在,正如其他人所指出的那样,这里有一些细微之处。请注意,规范清楚地指出,当块退出时,finally 执行。如果程序由failfast,堆栈溢出或某人将电源线拉出墙壁终止,那么该块永远不会退出!程序可以在块退出之前终止,因此最终不会运行。
答案 1 :(得分:1)
试试这段代码;终于永远不会被召唤:
static void Main()
{
try
{
Environment.FailFast("failed");
}
finally
{
Console.WriteLine("finally!");
}
}
答案 2 :(得分:0)
这意味着如果堆栈中的任何地方都没有catch子句,即如果异常未处理,那么abend会立即抛出异常:甚至在任何finally块之前都可以运行。
有关进一步的讨论和答案,请参阅C# Time of finally execution。
答案 3 :(得分:0)
最终声明通常会运行,但正如我所记得的那样(TheDailyWTF.com)的采访故事(http://thedailywtf.com/Articles/My-Tales.aspx),它并不总是如此。
我认为(我可能错了),StackOverflowException不会落入finally块。 (在ThedailyWTF.com上发布的另一个可爱的例子是一个简单的例子,如果拉动电源,则finally块将无法运行;))。
所以,要小心相信它会一直运行。
答案 4 :(得分:0)
不要忘记程序集的main方法不是堆栈中的第一个方法。下面还有其他几种方法(托管和非托管方法的混合)。这些方法加载执行的程序集,最后使用命令行参数调用main方法。
在Visual Studio中调试托管应用程序时,典型的调用堆栈如下所示:
MyProgram.exe!MyProgram.Program.Main(string[] args = {string[0]}) Line 15 C#
[Native to Managed Transition]
[Managed to Native Transition]
mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x3a bytes
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x66 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x6f bytes
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes
在这个调用堆栈的某个地方,可能有一个catch处理程序在出现未在用户代码中处理的异常时打印堆栈跟踪。但是,这是一个实现细节,它与specification的第12.4.2.5节没有冲突。