【问题标题】:Finally block does not execute as Microsoft say in it's Docfinally 块没有像微软在它的文档中所说的那样执行
【发布时间】:2020-10-22 12:30:13
【问题描述】:

Here微软说:

"通过使用 finally 块,您可以清理任何资源 在 try 块中分配,即使出现异常也可以运行代码 发生在 try 块中。”

并清楚地使用此示例来支持该想法:

public class ThrowTestA
{
    static void Main()
    {
        int i = 123;
        string s = "Some string";
        object obj = s;

        try
        {
            // Invalid conversion; obj contains a string, not a numeric type.
            i = (int)obj;

            // The following statement is not run.
            Console.WriteLine("WriteLine at the end of the try block.");
        }
        finally
        {
            // To run the program in Visual Studio, type CTRL+F5. Then
            // click Cancel in the error dialog.
            Console.WriteLine("\nExecution of the finally block after an unhandled\n" +
                "error depends on how the exception unwind operation is triggered.");
            Console.WriteLine("i = {0}", i);
        }
    }
    // Output:
    // Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
    //
    // Execution of the finally block after an unhandled
    // error depends on how the exception unwind operation is triggered.
    // i = 123
}

但是当我将它复制到我的 .Net-Core 控制台时,它最终没有执行,也没有最终返回我所期望的输出,根据微软所说!它在下面返回,我不知道为什么!

我知道我们可以简单地使用 try..catch 块来解决问题。我就是想知道这个与微软的样本和我的经历的矛盾!

【问题讨论】:

  • 我做到了,但没有任何改变
  • try {}finally {} 部分之间添加一个catch {} 块。
  • @imsmn 我知道,而且很简单!但我刚刚调查了 finally 块行为。为什么我们必须使用它?我们可以简单地删除它并在 catch 之后做任何我们想做的事情!喜欢免费资源等

标签: c# .net .net-core


【解决方案1】:

他们后来在同一篇论文中说

在处理的异常中,保证运行相关的 finally 块。但是,如果异常未处理,finally 块的执行取决于异常展开操作的触发方式。反过来,这取决于您的计算机的设置方式。

在您的情况下,异常未处理,因此不保证最终会被调用

【讨论】:

    【解决方案2】:

    在这里查看:

    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally

    在处理的异常中,保证运行相关的 finally 块。但是,如果异常未处理,finally 块的执行取决于异常展开操作的触发方式。反过来,这取决于您的计算机的设置方式。

    通常,当未处理的异常结束应用程序时,finally 块是否运行并不重要。但是,如果 finally 块中有语句,即使在这种情况下也必须运行,一种解决方案是在 try-finally 语句中添加一个 catch 块。或者,您可以捕获调用堆栈更高的 try-finally 语句的 try 块中可能引发的异常。也就是说,您可以在调用包含 try-finally 语句的方法的方法中,或在调用该方法的方法中,或在调用堆栈中的任何方法中捕获异常。如果没有捕获到异常,finally块的执行取决于操作系统是否选择触发异常展开操作。

    这通常是什么时候?

    如果没有捕获到异常,finally块的执行取决于操作系统是否选择触发异常展开操作。

    异常展开

    当我们用 try 语句包围代码块时,编译器会创建一个步骤来将 CPU 的当前上下文存储在当前堆栈帧中,程序计数器指向 catch 块的开始。如果 CPU 遇到任何错误,它会从堆栈中检索上下文,程序计数器会跳转到 catch 语句。

    Conditions when finally does not execute in a .net try..finally block

    一些例子:

    • 堆栈溢出异常
    • ExecutionEngineException
    • 应用程序退出

    【讨论】:

    • 那么,有了这个描述,我们为什么要使用 finally 块?我们可以删除它并在 catch 块之后执行我们想要的任何操作(例如释放资源等)。为什么我们必须使用finally?它的工作是什么?
    • @Mohammad see
    • 在这里查看这个:stackoverflow.com/questions/111597/…
    猜你喜欢
    • 1970-01-01
    • 2013-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多