是否有任何很小的可能性finally
不会被调用但应用程序仍在运行?
我在那里释放信号量
finally
{
_semParallelUpdates.Release();
}
并害怕失去其中的一些。
只有关键的终结者才有强有力的保证,以防万一砸到粉丝。您可以从CriticalFinalizerObject或SafeHandle继承 来获得此行为。但是,不建议让你的终结器做任何事情,而不是调用具有强可靠性合约的代码。例如,该代码必须能够在系统内存不足的情况下运行。
仅在您希望确保即使应用程序域已卸载(例如)也已清除所有未处理资源的情况下才需要实现关键终结器。请注意,您当然永远无法保证终结器会运行。万一停电,你就不走运了。如果您需要更多保证,则需要某种事务系统(例如数据库)来获得这种行为。
即使在未捕获的致命异常的最坏情况下,主机 Windows 操作系统也会终止程序。但是是的,即使在那种情况下,finally
块也肯定会被执行。
在 Framework 1.0 和 1.1 中,如果当前位于块中的线程finally
使用Thread.Abort
. 在当前版本的框架中,我不知道有任何此类情况。
如果您正在寻找使代码可靠的方法,我建议您阅读以下文章:
VinayC 推荐的另一篇优秀文章如下:
是否保证您的代码将到达finally
?是的(除非发生一些灾难性事件,例如世界末日……或者,您知道,您的计算机断电或操作系统崩溃)。
但重要的是要认识到,如果您的代码运行绝对关键,您最好确保您的代码本身不会引发异常!
以此为例:
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”块中死亡或被阻塞,执行将永远不会离开当前堆栈帧,但它也不会执行 finally“块”。