C# 最后:它在任何情况下都保证被调用吗

C# 最后:它在任何情况下都保证被调用吗,c#,.net,finally,C#,.net,Finally,是否有哪怕是很小的可能性,最终将不会被调用,但应用程序仍在运行 我在那里释放信号灯 finally { _semParallelUpdates.Release(); } 甚至在最坏的未捕获致命异常情况下,主机windows操作系统也会终止程序。但是是的,即使在这种情况下,finally块也肯定会被执行。在框架1.0和1.1中,如果当前在finally块中的线程使用thread.Abort中止。在当前版本的框架中,我不知道有

是否有哪怕是很小的可能性,
最终
将不会被调用,但应用程序仍在运行

我在那里释放信号灯

        finally
        {
            _semParallelUpdates.Release();
        }

甚至在最坏的未捕获致命异常情况下,主机windows操作系统也会终止程序。但是是的,即使在这种情况下,
finally
块也肯定会被执行。

在框架1.0和1.1中,如果当前在
finally
块中的线程使用
thread.Abort
中止。在当前版本的框架中,我不知道有任何这样的情况。

只有关键的终结器有很强的保证,可以在大便击中风扇时调用。您可以继承或获取此行为。但是,不建议让终结器执行具有强可靠性契约的调用代码以外的任何操作。例如,该代码必须能够在系统内存不足的情况下运行


只有在您希望确保即使卸载了应用程序域,也会清理所有未处理的资源的情况下,才需要实现关键终结器(例如,因为)。请注意,您当然无法保证终结器将运行。万一停电,你就倒霉了。如果您需要更多的保证,您需要某种事务系统(如数据库)来实现这种行为。

如果您正在寻找使代码可靠的方法,我建议您阅读以下文章:

VinayC推荐的另一篇优秀文章如下:


是否保证您的代码最终到达
(除非发生灾难性事件,如世界末日……或者,你知道,你的电脑断电或操作系统崩溃)

但认识到这一点很重要,如果代码运行非常关键,那么最好确保代码本身不会引发异常

以此为例:

IDisposable someDisposableObject = null;
IDisposable someOtherDisposableObject = null;

try
{
    someDisposableObject = GetDisposableObject();

    throw new Exception("Holy crap, something bad happened.");

    someOtherDisposableObject = GetOtherDisposableObject();
}
finally
{
    // This will throw a NullReferenceException...
    someOtherDisposableObject.Dispose();

    // ...so this actually won't run.
    someDisposableObject.Dispose();
}

因此,如果希望运行整个
finally
块,则必须正确编写它,以便(理想情况下)不可能出现异常。

当前线程不会离开当前堆栈帧,除非或直到“finally”块执行或从finally块本身引发异常。如果线程死亡或在“try”块中被阻塞,执行将永远不会离开当前堆栈帧,但它也不会执行最终的“块”。

是的,在终止情况下,由于应用程序崩溃,我不需要信号量;-)那么,我就不应该担心这个“潜在问题”了?这是不对的。如果出现致命异常,例如
ExecutingEngineException
,则不能保证将执行finally块。此外,在带外(异步)异常的情况下,例如
ThreadAbortException
StackOverflowException
OutOfMemoryException
,通常会终止执行线程,导致当前AppDomain被卸载,从而可能中断或根本无法到达最终块。请参阅以了解更多详细信息。副本的可能副本:@Oren a:呵呵,是的。您指出的线程也是以重复形式关闭的)在我的问题中,我想强调的是
最后
在关键情况下的行为,例如
堆栈溢出
或任何内存问题。我给出的链接也回答了这一问题。阅读超出接受答案的内容。“正确编写异常非常重要,以便(理想情况下)不可能发生异常”:这里的问题是异步(带外)异常,可能会在意外位置抛出,可能是每一条机器指令,如ThreadAbortException、StackOverflowException和OutOfMemoryException。因此,基本上,即使您到达finally块,它的执行也可能会中断,即使您的代码没有抛出同步异常。@0xA3:是的,这就是为什么我不能在没有限定符“理想”的情况下说“不可能”:显然,您无法确保异常是不可能的。也就是说,您可以尽最大努力确保不会因为
finally
块中的编码错误而引发异常。这就是我想说的。+1,这里有另一篇关于CER的文章:@VinayC:谢谢。的确是一篇很棒的文章。我把它添加到我的答案中是为了让链接更清晰。@David:如果那些文章为你提供了太多信息,那我很抱歉。这两篇参考文献都大约有10页A4打印纸,旨在简要介绍如何编写可靠的.NET代码。我想你找不到比斯蒂芬·图布自己写的那篇更好的文章了。