2010-04-07 12 views
7

He estado leyendo sobre Reliability Features in .NET y he escrito la siguiente clase para explorar ExecuteCodeWithGuaranteedCleanup¿Cuándo garantiza realmente ExecuteCodeWithGuaranteedCleanup la limpieza?

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

he experimentado con una variedad de cuerpos de código para el método Code. Estos, y sus resultados en tiempo de ejecución se enumeran a continuación

causando una OutOfMemoryException - Cleanupno significa ser llamado

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

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

    ss.Add(s); 
} 

Causando una StackOverflowException - Cleanupno significa ser llamado

Code(message); // recursive call 

Causando a ExecutionEngineException - Cleanupno ser llamado

Environment.FailFast(message.ToString()); 

Causando una ThreadAbortException-Cleanuphace ser llamado (sin embargo un habitual try...finally También se puede coger esta excepción)

Thread.CurrentThread.Abort(); 

Así que las preguntas son

  • ¿Estoy usando ExecuteCodeWithGuaranteedCleanup correctamente?
  • ¿Cuándo es realmente útil ExecuteCodeWithGuaranteedCleanup?
+1

Ejecute este código en un host CLR que implemente ICLRPolicyManager. Servidor SQL. –

Respuesta

2

Algunas excepciones son fatales para el proceso y la ejecución del código proporcionado por el usuario simplemente no continúa. El propósito del método ExecuteCodeWithGuaranteedCleanup es hacerlo para que pueda volver a colocar sus estructuras de datos en un estado consistente. Si el proceso va a morir de todos modos sin forma de detenerlo, esto no tiene ningún propósito. El sistema operativo (suponiendo que funcione correctamente) limpiará los objetos del kernel automáticamente cuando finalice un proceso, independientemente de la razón por la que finalice el proceso.

Como Hans insinúa, el ICLRPolicyManager del host entra en juego para determinar qué excepciones son fatales de esta manera cuando el código se ejecuta en un host particular (especialmente SQL Server). Consulte la cuadrícula agradable en la parte inferior de esta página de documentación: ICLRPolicyManager::SetActionOnFailure Method

Cuestiones relacionadas