【问题标题】:How to use try-finally construction in C#? [closed]如何在 C# 中使用 try-finally 构造? [关闭]
【发布时间】:2019-01-02 12:24:24
【问题描述】:

我们在这个论坛上看到了很多关于 try-catch-finallytry-finally 构造的问题。

答案的数量增加了问题的数量,所以我也很少。

这里是 a link 进入微软的解释 try-finally 构造。我已经读过了!

在下面的文章中写道:

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

  1. 我是否正确理解 try-catch-finally 构造 finally 将始终被执行? (不包括Environment.FastFail()

    我在这个论坛上读到过StackOverFlowException(在这种情况下没有执行finally 块),但是当我throw 它时,finally 块被执行。那么StackOverFlowException 呢?

  2. 为什么不调用finally 块?(在下面的代码中)?

  3. 对于哪些情况我们一般使用try-finally

  4. finally 块依赖于哪台 PC 设置?


using System;
namespace ConsoleApplication1
{
class Program
    {
    static void Main(string[] args)
        {
            try
            {
                throw  new Exception(); 
            }                              
            finally
            {
                Console.WriteLine("finally");
                Console.ReadKey();
            }
        }
    }
}    

【问题讨论】:

  • 这是 4.5 个问题;这可能会因为过于宽泛而被关闭。
  • 通常你的 finally 总是被运行,所以你可以让你的对象处理并关闭所有创建的内存泄漏。关于如何配置您的计算机的问题我不知道...
  • “这个论坛”不想成为一个论坛。
  • 这个 finally 块应该运行。你知道如何在调试器中继续,对吧?

标签: c# try-catch-finally finally try-finally


【解决方案1】:
  1. 是的,在大多数情况下,如果您不使用 Environment.Exit(0)Application.Exit() 之类的东西(就像普通人在他的回答中提到的那样)中止执行,则始终会执行 finally 块。

    对于 StackOverFlowException 和其他深度应用程序崩溃,它无法运行,因为当堆栈已满时,此线程中没有剩余内存来执行任何正常操作。因此,当您自己抛出异常时,没有真正的完整堆栈,应用程序可以继续运行。

  2. finally-block 不会在调试器中调用,因为如果顶层存在未处理的异常,调试器会立即关闭,因为没有顶层异常处理程序。请参阅this answer 以获得更深入的解释。如果您在没有附加调试器的情况下运行应用程序,最终块将被调用 - 感谢 bommelding 解决了这一问题。

  3. 每次需要确保正确清理时都使用 finally 块。请参阅this answer 以获得更深入的解释。

  4. 这是一个棘手的问题,我认为这是为了描述 PC 设置的影响,例如病毒扫描程序在尝试创建缓冲区溢出或类似的可能危急情况时终止程序。同样,finally 块的执行可以通过data execution prevention 或其他安全功能来阻止。

【讨论】:

  • re 2:它绝对应该运行。
  • @bommelding 我一开始也这么认为 - 但不,它不会运行 - 请参阅链接的答案并自己尝试。它不运行。
  • 好的,它不能在调试器中运行,我的错。点击 Ctrl+F5 然后“关闭程序”。你会看到“终于”。
  • 你说得对,这很有趣。我会相应地编辑我的答案。
【解决方案2】:

1.我是否正确理解在 try-catch-finally 中构造 finally 将始终被执行? (不包括Environment.FastFail()

在几个独特的情况下,在 return 之后不会调用 finally 块:如果首先调用 System.exit(),或者如果 VM 崩溃。

2.为什么finally块没有被调用?(在下面的代码中)?

在这里阅读:Can a finally block be interrupted/suspended?

  1. 我们一般在哪些情况下使用 try-finally?

try{} finally{} 应该用于无法处理异常但需要清理资源的情况。

或者,在我们的程序中发生一些异常异常之后,显示一些东西并优雅地退出总是更好。

【讨论】:

    【解决方案3】:

    1 - 视情况而定。使用 finally 块的想法是清理在 try 块中分配的资源。即使 try 块中发生异常,您也可以在 finally 块中运行代码。但是,finally 块保证在已处理的异常中运行。如果异常未处理,finally 的执行取决于异常展开操作的触发方式。

    2 - 由于未处理异常,因此未调用您的 finally。 Microsoft 文档指出“通常,当未处理的异常结束应用程序时,finally 块是否运行并不重要。但是,如果 finally 块中有语句即使在这种情况下也必须运行,一种解决方案是添加try-finally 语句的 catch 块。”比较https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-finally 的示例,了解已处理异常和未处理异常之间的区别。

    阅读更多关于这个问题Why use finally in C#?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      • 2014-09-30
      • 1970-01-01
      相关资源
      最近更新 更多