3

是否有任何很小的可能性finally不会被调用但应用程序仍在运行?

我在那里释放信号量

        finally
        {
            _semParallelUpdates.Release();
        }

并害怕失去其中的一些。

4

6 回答 6

1

只有关键的终结者才有强有力的保证,以防万一砸到粉丝。您可以从CriticalFinalizerObjectSafeHandle继承 来获得此行为。但是,不建议让你的终结器做任何事情,而不是调用具有强可靠性合约的代码。例如,该代码必须能够在系统内存不足的情况下运行。

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

于 2010-09-13T10:09:23.297 回答
0

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

于 2010-09-13T10:01:49.037 回答
0

在 Framework 1.0 和 1.1 中,如果当前位于块中的线程finally使用Thread.Abort. 在当前版本的框架中,我不知道有任何此类情况。

于 2010-09-13T10:03:49.970 回答
0

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

可靠性最佳实践

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

Stephen Toub:使用 .NET Framework 的可靠性特性保持代码运行

于 2010-09-13T10:13:00.603 回答
0

是否保证您的代码将到达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块,那么正确编写它非常重要,这样(理想情况下)就不可能出现异常。

于 2010-09-13T10:18:30.903 回答
0

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

于 2011-09-08T02:14:47.040 回答