Definition of when finally is executed [duplicate]

我是研究僧i 提交于 2020-01-06 16:54:00

问题


Possible Duplicates:
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 states that the finally block doesn't always run. That's wrong, right?

The ECMA standard for the CLI (from which C# derives its exception features) states that exceptions are handled in a two-pass search of the stack.[13] The first pass attempts to locate a matching catch block, and terminates the program if none is found. Only if a matching catch block is found does the second pass execute, which runs the intervening finally blocks. This allows the problem to be diagnosed without the program state first being modified by the finally blocks; it also eliminates the risk that finally blocks may have undesirable side-effects when the program is in an unknown state (such as corruption of external data, or throwing further exceptions).

But, I don't need a catch to finally execute:

    static void Main()
    {
        try { throw new Exception(); }
        finally
        {
            Console.WriteLine("1");
        }
    }

回答1:


I notice that no one has actually answered your question, which is "is this text correct?"

No, it is not correct, in that it omits an important point.

The relevant portion of the CLI specification which it fails to quote is section 12.4.2 of Partition I, which states:


A finally handler ... shall be executed whenever the block exits, regardless of whether that occurs by normal control flow or by an unhandled exception.


Now, as others have noted, there are some subtleties here. Notice that the specification clearly calls out that the finally is executed when the block exits. If the program is terminated by a failfast, by a stack overflow, or by someone pulling the power cord out of the wall, then the block never exits! The program could be terminated before the block exits, and therefore the finally would not run.




回答2:


Try this code; finally is never called:

    static void Main()
    {
        try 
        {
            Environment.FailFast("failed");
        }
        finally
        {
            Console.WriteLine("finally!");
        }
    }



回答3:


It implies that if there's no catch clause anywhere on the stack, i.e. if the exception is unhandled, then the abend is immediate at the point at which the exception is thrown: even before any finally blocks can be run.

See C# Time of finally execution for further discussion and answers.




回答4:


The finally statement will usually run, but as has been pointed out in one of (as far as I recall), TheDailyWTF.com's tales from the interview (http://thedailywtf.com/Articles/My-Tales.aspx), it doesn't always run.

I think (and I could be wrong on this), a StackOverflowException will not fall into a finally block. (The other lovely example that was posted in ThedailyWTF.com is a simple case of, the finally block won't run if the power is pulled ;)).

So, beware of believing that it will always run.




回答5:


Don't forget that your assembly's main method is not the first method on the stack. There are several other methods (a mix of managed and unmanaged methods) below. These methods load your executing assembly, and finally call the main method with the command line arguments.

A typical call stack when debugging a managed application in Visual Studio looks like this:

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   

Somewhere on this call stack there might be a catch handler that prints the stack trace in case of an exception that has not been handled in user code. However, this is an implementation detail, and it doesn't conflict with section 12.4.2.5 of the specification.



来源:https://stackoverflow.com/questions/2048493/definition-of-when-finally-is-executed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!