2010-04-07 13 views
7

Ho letto su Reliability Features in .NET e ho scritto la seguente classe di esplorare ExecuteCodeWithGuaranteedCleanupQuando ExecuteCodeWithGuaranteedCleanup garantisce effettivamente la pulizia?

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(); 
    } 
} 

ho sperimentato con una varietà di corpi codice per il metodo Code. Questi, ed i loro risultati di runtime sono elencati di seguito

causando un OutOfMemoryException-Cleanupnon significa ottenere chiamato

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

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

    ss.Add(s); 
} 

Causando un StackOverflowException - Cleanupnon significa ottenere chiamato

Code(message); // recursive call 

Causando a ExecutionEngineException - Cleanupnon ottenere chiamato

Environment.FailFast(message.ToString()); 

Causando un ThreadAbortException-Cleanupfa ottenere chiamato (comunque un regolare try...finally può anche prendere questa eccezione)

Thread.CurrentThread.Abort(); 

Quindi le domande sono

  • Sto usando ExecuteCodeWithGuaranteedCleanup correttamente?
  • Quando è effettivamente utile il ExecuteCodeWithGuaranteedCleanup?
+1

Eseguire questo codice su un host CLR che implementa ICLRPolicyManager. Server SQL. –

risposta

2

Alcune eccezioni sono fatali per il processo e l'esecuzione del codice fornito dall'utente non continua. Lo scopo del metodo ExecuteCodeWithGuaranteedCleanup è quello di consentire la restituzione delle strutture dati in uno stato coerente. Se il processo sta per morire in ogni modo senza alcun modo per fermarlo, questo non ha scopo. Il sistema operativo (supponendo che funzioni correttamente) pulirà automaticamente tutti gli oggetti del kernel al termine di un processo, indipendentemente dal motivo del processo.

Come suggerisce Hans, lo ICLRPolicyManager dell'host entra in gioco per determinare quali eccezioni sono fatali in questo modo quando il codice viene eseguito in un particolare host (in particolare SQL Server). Vedere la bella griglia nella parte inferiore di questa pagina di documentazione: ICLRPolicyManager::SetActionOnFailure Method

Problemi correlati