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代码。我想你找不到比斯蒂芬·图布自己写的那篇更好的文章了。