En general sí, finalmente se ejecutará.
Para los siguientes tres escenarios, el SIEMPRE se ejecutará SIEMPRE :
- No se producen excepciones.
- Excepciones sincrónicas (excepciones que ocurren en el flujo normal del programa).
Esto incluye excepciones compatibles con CLS que se derivan de System.Exception y excepciones no compatibles con CLS, que no se derivan de System.Exception. RuntimeWrappedException ajusta automáticamente las excepciones que no cumplen con CLS. C # no puede lanzar excepciones de reclamos que no sean de CLS, pero sí pueden lenguajes como C ++. C # podría estar llamando a un código escrito en un lenguaje que puede generar excepciones no compatibles con CLS.
- ThreadAbortException asíncrona
A partir de .NET 2.0, una ThreadAbortException ya no impedirá que finalmente se ejecute. ThreadAbortException ahora se iza antes o después de finalmente. El finalmente siempre se ejecutará y no será interrumpido por un aborto de hilo, siempre que el intento se haya introducido antes de que ocurriera el aborto de hilo.
El siguiente escenario, el finalmente no se ejecutará:
StackOverflowException asíncrono.
A partir de .NET 2.0, un desbordamiento de la pila hará que el proceso finalice. Finalmente, no se ejecutará, a menos que se aplique una restricción adicional para que finalmente sea un CER (Región de ejecución restringida). Los CER no deben usarse en el código de usuario general. Solo deben usarse donde sea crítico que el código de limpieza siempre se ejecute, ya que de todos modos el proceso se está cerrando en el desbordamiento de la pila y, por lo tanto, todos los objetos administrados se limpiarán de manera predeterminada. Por lo tanto, el único lugar donde un CER debería ser relevante es para los recursos que se asignan fuera del proceso, por ejemplo, los identificadores no administrados.
Por lo general, el código no administrado lo envuelve alguna clase administrada antes de ser consumido por el código de usuario. La clase de contenedor administrado generalmente utilizará un SafeHandle para ajustar el identificador no administrado. SafeHandle implementa un finalizador crítico y un método de lanzamiento que se ejecuta en un CER para garantizar la ejecución del código de limpieza. Por este motivo, no debería ver CERs llenos de código de usuario completo.
Entonces, el hecho de que finalmente no se ejecute en StackOverflowException no debería tener ningún efecto en el código del usuario, ya que el proceso finalizará de todos modos. Si tiene algún caso límite en el que necesita limpiar algún recurso no administrado, fuera de SafeHandle o CriticalFinalizerObject, utilice un CER de la siguiente manera; pero tenga en cuenta que esta es una mala práctica: el concepto no administrado debe abstraerse a una (s) clase (s) administrada (s) y SafeHandle (s) apropiados por diseño.
p.ej,
// No code can appear after this line, before the try
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This is *NOT* a CER
}
finally
{
// This is a CER; guaranteed to run, if the try was entered,
// even if a StackOverflowException occurs.
}