50

基本上我听说某些条件会导致 .net 吹过 finally 块。有谁知道这些条件是什么?

4

7 回答 7

54

两种可能:

当存在 a 时,finally 块将不会被执行,StackOverflowException因为堆栈上没有空间可以执行更多代码。当存在 时,它也不会被调用ExecutionEngineException,这可能来自对 的调用Environment.FailFast()

于 2008-09-21T18:23:38.617 回答
15

除非 CLR 因 ExecutingEngineException 而崩溃并崩溃(我在 .net 1.1 中看到过一些只有适量的 COM Interop :) .. 我认为 finally 应该始终执行。

于 2008-09-21T18:21:28.683 回答
6

您可能会遇到这样的情况:try 块中的代码导致在进入 try 块之前引发 SecurityException(而不是在调用包含方法时引发异常(请参阅http://msdn.microsoft.com/en-us /library/fk6t46tz(VS.71).aspx )),在这种情况下,您甚至永远不会进入 try 块,因此永远不会调用 finally 块中的代码。

其他可能性包括 StackOverflowException 和 ExecutingEngineException。

于 2008-09-21T18:28:27.590 回答
4

Finally阻止background thread可能无法执行。但是,这取决于甚至在完全执行之前main foreground thread终止background thread操作的完成执行background thread

class Program
{

    static void Main(string[] args)
    {
        Program prgm = new Program();
        Thread backgroundThread = new Thread(prgm.CheckBgThread);
        backgroundThread.IsBackground = true;
        backgroundThread.Start();
        Console.WriteLine("Closing the program....");
    }

    void CheckBgThread()
    {
        try
        {
            Console.WriteLine("Doing some work...");
            Thread.Sleep(500);
        }
        finally
        {
            Console.WriteLine("This should be always executed");
        }
    }
}
于 2016-11-21T14:05:20.750 回答
2

还有 Application.Exit 方法。

于 2008-12-20T20:29:52.490 回答
0

finally 块之后的代码和外部范围内的代码都不会在 finally 块首先启动的情况下执行(finally 块中的异常可能导致它过早退出,在这种情况下,执行将从终结器跳到外部范围)。如果 finally 块之前的代码陷入无限循环或永远不会退出的方法,或者如果执行上下文被完全销毁,finally 块将不会执行。

请注意,依赖 finally 块是正确的,这与不应正确依赖的“Finalize”方法(或 C#“析构函数”)不同。

于 2011-09-21T20:03:22.133 回答
0

由于 async/await,还有另一种方法 finally 可能会被忽略,这是我在其他答案中没有提到的:

static class Program
{
    [STAThread]
    static void Main()
    {
        async void ThreadExecutionAsync()
        {
            try
            {
                SynchronizationContext.SetSynchronizationContext(
                    new WindowsFormsSynchronizationContext());

                await Task.Yield(); // Yield to the context

                // The WindowsFormsSynchronizationContext will schedule the continuation
                // on the main thread, so the current thread will die
                // and we will never get here...
                Debugger.Break();
            }
            finally
            {
                // Will never get here either...
                Debugger.Break();
            }
        }

        var thread = new Thread(ThreadExecutionAsync);
        thread.Start();

        Application.Run();
    }
}
于 2020-06-05T14:05:56.677 回答