2010-09-13 39 views
3

要調用是否有任何哪怕是很小的可能性finally將不會被調用,但應用程序仍在運行?最後:這是保證在任何情況下

我釋放信號量有

 finally 
     { 
      _semParallelUpdates.Release(); 
     } 

和害怕失去他們中的一些。

+0

可能的重複副本:http://stackoverflow.com/questions/3216046/does-the-c-finally-block-always-execute-closed – 2010-09-13 10:05:17

+0

@Oren A:嘿,是的。並指出線程也被關閉爲重複)))作爲我的問題,我想強調'最後'的行爲在關鍵情況下,如'Stackoverflow'或任何內存問題 – zerkms 2010-09-13 10:07:03

+1

這也是答案在鏈接I給。超出接受的答案閱讀。 – 2010-09-13 10:10:27

回答

0

如果您正在尋找辦法,使你的代碼可靠的,我建議您閱讀以下文章:

Reliability Best Practices

通過VinayC推薦的另一個優秀文章如下:

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

+0

+1,這裏是另一篇關於CER的文章:http://msdn.microsoft.com/en-us/magazine/cc163716.aspx – VinayC 2010-09-13 10:39:01

+0

@VinayC:謝謝。確實是一篇很棒的文章我將它添加到我的答案中,使鏈接更加明顯。 – 2010-09-13 11:10:58

+0

-1鏈接到一個簡單問題的100頁文章 – David 2012-04-23 13:23:13

0

主機Windows操作系統會甚至在未捕獲的致命異常最壞的情況下終止程序。但是,即使在這種情況下finally塊肯定會得到執行。

+0

是的,在終止的情況下,我不需要信號量,因爲應用程序崩潰;-)那麼,那麼我不應該擔心這個「潛在問題」呢? – zerkms 2010-09-13 10:04:17

+0

這是不正確的。在致命異常(例如ExecutingEngineException)的情況下,不能保證將執行finally塊。此外,對於帶外(異步)異常(例如ThreadAbortException,StackOverflowException和OutOfMemoryException),通常執行的線程會終止,導致當前的AppDomain被卸載,從而導致finally塊可能被中斷達成了。有關更多詳細信息,請參見[可靠性最佳實踐](http://msdn.microsoft.com/zh-cn/library/ms228970.aspx)。 – 2010-09-13 10:33:47

0

在Framework 1.0和1.1中,this was possible如果當前在finally塊中的線程使用Thread.Abort中止。在當前版本的框架中,我不知道有這種情況。

1

只有關鍵的終結都被稱爲強擔保的情況下,狗屎打扇。您可以繼承CriticalFinalizerObjectSafeHandle以獲得此行爲。但是,不建議讓您的終結器執行任何操作,而不是使用強大的可靠性合同調用代碼。例如,在系統內存不足的情況下,該代碼必須能夠運行。

實現關鍵終結只需要在你要確保,即使應用程序域被卸載所有未處理的資源被清洗的情況下(因爲實例)。請注意,你當然從來沒有任何保證終結者將運行。如果發生電力故障,您的運氣不好。如果你需要更多的保證,你需要某種類型的交易系統(如數據庫),可以讓你這種行爲。

0

是它保證你的代碼將達到finally(除了一些災難性事件,如世界即將結束......或者,你知道,你的電腦失去權力或你的操作系統崩潰)。

但是重要的是要認識到,如果代碼運行絕對至關重要,那麼最好確保代碼本身不會引發異常!如果你想運行你整個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(); 
} 

,把它寫正確,這樣的例外是比較理想的狀況不可能是很重要的:

拿這個舉例來說。

+0

「正確編寫它是非常重要的,這樣一個異常(理想情況下)是不可能的」:這裏的問題是異常(帶外)異常,可能會在意外的位置拋出,可能是每個機器指令,如ThreadAbortException,StackOverflowException,和OutOfMemoryException。因此,即使你*達到* finally塊,即使你的代碼沒有拋出同步異常,它的執行也可能被中斷。 – 2010-09-13 10:31:38

+0

@ 0xA3:是的,基本上這就是爲什麼我無法讓自己說「不可能」沒有限定詞「理想」:顯然你永遠不能確保例外*不可能*。也就是說,您*可以*盡最大努力確保在*'finally'塊內由於自己的編碼錯誤*不會拋出異常。我就是這麼想的。 – 2010-09-13 10:46:07

0

當前線程不會離開當前堆棧幀,除非或直到finally塊執行或從finally塊本身內引發異常。如果一個線程在「try」塊中死亡或被阻塞,執行永遠不會離開當前的堆棧幀,但它也不會執行finally塊。