2010-04-07 125 views
7

我一直在閱讀有關Reliability Features in .NET並寫了下面的類來探索ExecuteCodeWithGuaranteedCleanup什麼時候ExecuteCodeWithGuaranteedCleanup實際上保證清理?

class Failing 
{ 
    public void Fail() 
    { 
     RuntimeHelpers.PrepareConstrainedRegions(); 
     try 
     { 
     } 
     finally 
     { 
      RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(Code, Cleanup, "fail"); 
     } 
    } 

    private void Code(object message) 
    { 
     // Some code in here that will cause an exception... 
    } 

    private void Cleanup(object message, bool something) 
    { 
     Console.WriteLine(message); 
     Console.ReadLine(); 
    } 
} 

我已經用各種的方法Code代碼體實驗。這些,他們的運行結果如下所列

中導致OutOfMemoryException - Cleanup被調用

List<string> ss = new List<string>(); 

while (true) 
{ 
    string s = new string('x', 1000000); 

    ss.Add(s); 
} 

造成StackOverflowException - Cleanup被調用

Code(message); // recursive call 

曹景偉a ExecutionEngineException - Cleanup被調用

Environment.FailFast(message.ToString()); 

造成ThreadAbortException - Cleanup確實被調用(但經常try...finally還可以趕上這個異常)

Thread.CurrentThread.Abort(); 

所以問題是

  • 我正確使用ExecuteCodeWithGuaranteedCleanup嗎?
  • 什麼時候是ExecuteCodeWithGuaranteedCleanup實際上有用?
+1

在實現ICLRPolicyManager的CLR主機上運行此代碼。 SQL Server。 – 2010-04-07 12:45:40

回答

2

一些異常對進程是致命的,並且用戶提供的代碼的執行不會繼續。 ExecuteCodeWithGuaranteedCleanup方法的目的是爲了讓您可以將數據結構恢復到一致的狀態。如果這個過程無論如何都無法阻止它,那就沒有任何目的。無論過程結束的原因,操作系統(假設它正常工作)都會在進程結束時自動清理所有內核對象。

正如Hans提示的那樣,主機的ICLRPolicyManager可以用來確定在特定主機(尤其是SQL Server)中運行代碼時,哪種異常是致命的。請參閱本文檔頁面底部的漂亮網格:ICLRPolicyManager::SetActionOnFailure Method

相關問題