最终没有在.net中执行的条件try..finally阻止

时间:2008-09-21 18:18:37

标签: .net exception-handling

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

7 个答案:

答案 0 :(得分:49)

两种可能性:

当存在StackOverflowException时,不会执行finally块,因为堆栈上没有空间来执行更多代码。当ExecutionEngineException出现Environment.FailFast()时也不会调用它,这可能是因为调用{{1}}而产生的。

答案 1 :(得分:15)

除非CLR爆炸并且因ExecutingEngineException而崩溃(我在.net 1.1天中看到了一些只有适当数量的COM Interop :) ..我认为最终总是执行。

答案 2 :(得分:6)

你可以得到这样的情况:try块中的代码导致在输入try块之前抛出SecurityException(而不是在调用包含方法时抛出异常(参见http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx)),在此你永远不会进入try块的情况,所以finally块中的代码永远不会被调用。

其他可能性包括StackOverflowException和ExecutingEngineException。

答案 3 :(得分: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"); } } }

_clone: function(obj){
    let newObj = {};
    for(let i in obj){
        if(typeof(obj[i]) === 'object' && Object.keys(obj[i]).length){
            newObj[i] = clone(obj[i]);
        } else{
            newObj[i] = obj[i];
        }
    }
    return Object.assign({},newObj);
}

答案 4 :(得分:2)

还有Application.Exit方法。

答案 5 :(得分:0)

最后一个块之后的代码和外部作用域中的代码都不会先执行finally块而不执行finally块(finally块中的异常可能导致它过早退出,在这种情况下执行将从终结者到外部范围)。如果finally块之前的代码卡在无限循环或永不退出的方法中,或者执行上下文被完全销毁,则finally块将不会执行。

请注意,依赖finally块是合适的,不像“Finalize”方法(或C#“析构函数”),这些方法不应该被依赖。

答案 6 :(得分:0)

自从异步/等待以来,还有另一种可能最终被忽略的方法,而我在其他答案中没有提到过:

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();
    }
}