最终执行时的定义

时间:2010-01-12 11:25:29

标签: c# command-line-interface

  

可能重复:
  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");
        }
    }

5 个答案:

答案 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节没有冲突。