C#终于执行的时间 [英] C# Time of finally execution

查看:146
本文介绍了C#终于执行的时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

采取以下代码:

using System;

namespace OddThrow
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                throw new Exception("Exception!");
            }
            finally
            {
                System.Threading.Thread.Sleep(2500);
                Console.Error.WriteLine("I'm dying!");
                System.Threading.Thread.Sleep(2500);
            }
        }
    }
}

其中给我这个输出:

Unhandled Exception: System.Exception: Exception!
   at OddThrow.Program.Main(String[] args) in C:\Documents and Settings\username
\My Documents\Visual Studio 2008\Projects\OddThrow\OddThrow\Program.cs:line 14
I'm dying!

我的问题是:为什么未处理的异常文本发生在finally之前?在我看来,在我们甚至知道这个异常是未处理的之前,最终应该被排除在堆栈展开之前。请注意对Sleep()的调用 - 在未处理的异常被打印之后,这些发生就像以下一样:

My question is: why does the unhandled exception text occur before the finally's? In my mind, the finally should be excuted as the stack unwinds, before we even know that this exception is unhandled. Note the calls to Sleep() - these occur after the unhandled exception is printed, as if it was doing this following:


  1. 未处理的异常文本/消息

  2. 最后阻止。

  3. 终止应用程序

根据C#标准§8.9.5,这种行为是错误的:

According to the C# standard, §8.9.5, this behaviour is wrong:


  • 在当前函数成员,检查包围投影点的每个try语句。对于每个语句S,从最内层的try语句开始,以最外层的try语句结尾,将评估以下步骤:


    • 如果try块的S包含抛出点,如果S有一个或多个catch子句,则catch子句将按照外观的顺序进行检查,以便为异常找到合适的处理程序。指定异常类型或异常类型的基类型的第一个catch子句被认为是一个匹配项。一般的catch子句(§8.10)被认为是任何异常类型的匹配项。如果找到匹配的catch子句,则通过将控件转移到该catch子句的块来完成异常传播。


    • 否则,如果try块或S的catch块包围投掷点,如果S有一个finally块,则控制转移到finally块。如果finally块抛出另一个异常,则当前异常的处理被终止。否则,当控件到达finally块的终点时,继续处理当前异常。

    我哪里错了? (我有一些自定义的控制台错误消息,这是一种方式,轻微,只是烦人,让我质疑语言...)

    Where am I going wrong? (I've got some custom console error messages, and this is in-the-way. Minor, just annoying, and making me question the language...)

    推荐答案

    关于执行顺序的标准声明是正确的,与您观察到的不一致。允许未处理的异常消息出现在过程中的任何点,因为它只是来自CLR的消息,实际上并不是异常处理程序本身。关于执行顺序的规则仅适用于在CLR内执行的代码,而不适用于CLR本身所执行的代码。

    The standard's statements about the order of execution are correct, and not inconsistent with what you are observing. The "Unhandled exception" message is allowed to appear at any point in the process, because it is just a message from the CLR, not actually an exception handler itself. The rules about order of execution only apply to code being executed inside the CLR, not to what the CLR itself does.

    您实际执行的操作是公开实现细节,这是未经处理的异常通过查看尝试我们在里面的{}块的堆栈来识别,而不是通过实际探索一直到根。通过查看此堆栈可能会执行或可能不处理异常,但未处理的异常将以此方式被识别。

    What you've actually done is expose an implementation detail, which is that unhandled exceptions are recognised by looking at a stack of which try{} blocks we are inside, rather than by actually exploring all the way to the root. Exceptions may or may not be handled by looking at this stack, but unhandled exceptions are recognised this way.

    如您所知,如果您在主函数中放置顶级try {} catch {},然后您将看到您期望的行为:在检查下一个框架以获取匹配的catch {}之前,将执行每个函数的最终执行。

    As you may be aware, if you put a top-level try{}catch{} in your main function, then you will see the behaviour you expect: each function's finally will be executed before checking the next frame up for a matching catch{}.

    这篇关于C#终于执行的时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆