最后:保证在任何情况下都可以调用它

时间:2010-09-13 09:58:55

标签: c# .net finally

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

我在那里发布信号量

        finally
        {
            _semParallelUpdates.Release();
        }

并且害怕失去其中一些人。

6 个答案:

答案 0 :(得分:1)

只有关键终结者有强大的保证,以便在狗屎击中风扇的情况下被召唤。您可以继承CriticalFinalizerObject SafeHandle来获取此行为。但是,不建议让终结器除了使用强可靠性合同调用代码之外做任何其他事情。例如,在系统内存不足的情况下,此代码必须能够运行。

只有在您希望确保清除所有未处理的资源时,即使卸载应用程序域(例如),也只需要实现关键终结器。请注意,您当然永远不会保证终结器会运行。如果发生电源故障,你就不走运了。如果您需要更多保证,您需要某种可以帮助您实现这种行为的事务系统(例如数据库)。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

  

<强> Reliability Best Practices

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

  

<强> Stephen Toub: Keep Your Code Running with the Reliability Features of the .NET Framework

答案 4 :(得分: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块,则正确编写它是非常重要的,以便(理想情况下)不会发生异常。

答案 5 :(得分:0)

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