Existen tres tipos de las llamadas "excepciones asincrónicas". Esa es la excepción ThreadAbortException, la OutOfMemoryException y la StackOverflowException mencionada. Esas excepciones pueden ocurrir en cualquier instrucción en su código.
Y, también hay una manera de superarlos:
La más sencilla es la ThreadAbortException. Cuando el código actual se ejecuta en un bloque final. ThreadAbortExceptions se "mueve" al final del bloque finally. Entonces, todo en un bloque final no puede ser abortado por una ThreadAbortException.
Para evitar una OutOfMemoryException, solo tiene una posibilidad: no asigne nada en el Heap. Esto significa que no tiene permitido crear ningún tipo de referencia nuevo.
Para superar la StackOverflowException, necesita ayuda del Framework. Esta ayuda se manifiesta en regiones de ejecución restringida. La pila requerida se asigna antes de el código real se ejecuta y, además, también garantiza que el código ya está compilado en JIT y, por lo tanto, está disponible para su ejecución.
Hay tres formas de ejecutar código en las Regiones de ejecución constreñidos (copiados de la BCL Team Blog):
- ExecuteCodeWithGuaranteedCleanup, una forma segura pila desbordamiento de un try/finally.
- Un bloque try/finally precedido inmediatamente por una llamada a RuntimeHelpers.PrepareConstrainedRegions. El bloque try no está restringido, pero todos los bloqueos catch, finally y fault para ese intento son.
- Como finalizador crítico: cualquier subclase de CriticalFinalizerObject tiene un finalizador que está ansiosamente preparado antes de asignar una instancia del objeto.
- Un caso especial es el método ReleaseHandle de SafeHandle, un método virtual que se prepara ansiosamente antes de que se asigne la subclase, y se llama desde el finalizador crítico de SafeHandle.
Puede encontrar más información en estas publicaciones en el blog:
Constrained Execution Regions and other errata [Brian Grunkemeyer] en el blog de BCL equipo.
Joe Duffy's Weblog about Atomicity and asynchronous exception failures donde ofrece una muy buena visión general sobre las excepciones asincrónicas y la solidez en el .NET Framework.
Me resulta algo sorprendente, después de todo el CLR es el código propiedad de Microsoft, podrían haber ahorrado algunos marcos de pila para permitir el manejo de excepciones. – adams
¿Cómo sabría cuánto reservar? En una situación de desbordamiento de la pila, la pila ha crecido a un tamaño tal que no es manejable. Al reservar un espacio, deberá reservar el tamaño máximo de pila, lo que a su vez equivaldría a la mitad de la pila disponible para el software. – blowdart
Ok, entiendo esta idea ... Algo así como ... En un entorno de subproceso único. Pero bueno, podríamos crear más de un hilo, ¿no? Y cada hilo tiene una pila separada, ¿no? Entonces, ¿por qué terminar todo el proceso cuando solo un subproceso se quedó sin pila? –