Condiciones cuando finalmente no se ejecuta en un .net try … bloque final

Básicamente, he oído que ciertas condiciones provocarán que .net sople al bloque final. ¿Alguien sabe cuáles son esas condiciones?

Dos posibilidades:

  • StackOverflowException
  • ExecutionEngineException

El bloque finally no se ejecutará cuando exista StackOverflowException ya que no hay espacio en la stack para ejecutar más código. Tampoco se llamará cuando exista ExecutionEngineException , que puede surgir de una llamada a Environment.FailFast() .

A menos que el CLR explote y caiga con ExecutingEngineException (he visto algunos en .net 1.1 días con la cantidad justa de COM Interop 🙂 … creo que finalmente siempre debería ejecutarse.

Puede obtener una situación en la que el código en el bloque try causa que se genere una SecurityException antes de que se ingrese el bloque try (en su lugar, se lanza la excepción cuando se llama al método que lo contiene (consulte http://msdn.microsoft.com/en-us). /library/fk6t46tz(VS.71).aspx )), en esta situación nunca ingresas al bloque try para que nunca se invoque el código en el bloque finally.

Otras posibilidades incluyen StackOverflowException y ExecutingEngineException.

Finally bloque en el background thread puede no ejecutarse. Sin embargo, depende de la ejecución completa del main foreground thread que finaliza background thread operación del background thread incluso antes de la ejecución completa del background thread de background thread .

 class Program { static void Main(string[] args) { Program prgm = new Program(); Thread backgroundThread = new Thread(prgm.CheckBgThread); backgroundThread.IsBackground = true; backgroundThread.Start(); Console.WriteLine("Closing the program...."); } void CheckBgThread() { try { Console.WriteLine("Doing some work..."); Thread.Sleep(500); } finally { Console.WriteLine("This should be always executed"); } } } 

También hay el método Application.Exit.

Ni el código que sigue a un bloque final, ni el código en ámbitos externos, se ejecutarán sin que el bloque finally haya sido iniciado primero (una excepción dentro del bloque finally puede causar que salga prematuramente, en cuyo caso la ejecución saltará del finalizador a un scope externo). Si el código anterior al bloque finally se atasca en un bucle infinito o un método que nunca se cierra, o si el contexto de ejecución se destruye por completo, el bloque finally no se ejecutará.

Tenga en cuenta que es apropiado confiar en los bloques finalmente, a diferencia de los métodos de “Finalización” (o “destructores” de C #) que no se deben confiar de forma adecuada.