Todo mi conocimiento sobre este tema está tomado de este artículo aquí: http://msdn.microsoft.com/en-us/magazine/cc793966.aspx - tenga en cuenta que está escrito para .NET 2.0, pero tengo la sensación de que tiene sentido para lo que estábamos experimentando en este caso (más que "porque decidido" de todos modos)
rápida 'no tengo tiempo para leer ese artículo' respuesta (aunque se debe, que es una muy buena):
la solución al problema (si usted absolutamente tiene que tener su finalmente bloquea ejecutar) sería a) poner un controlador de error global o b) forzar .NET para ejecutar finalmente bloques y hacer las cosas de la forma en que lo hizo (posiblemente de manera incorrecta) en .NET 1.1 - Coloque lo siguiente en su aplicación .config:
<legacyUnhandledExceptionPolicy enabled="1">
La razón para ello: Cuando se produce una excepción en .NET que empieza a caminar hacia atrás a través de la pila en busca de controladores de excepciones y cuando lo encuentra, entonces hace un segundo camino de vuelta a través de la pila en funcionamiento bloques finally antes de ejecutar el contenido de la captura. Si no encuentra una captura, esta segunda caminata nunca ocurre, por lo que los bloques finally nunca se ejecutan aquí, por lo que un manejador global de excepciones siempre ejecutará cláusulas finally ya que la CLR las ejecutará cuando encuentre la captura, NO cuando la ejecute (lo cual creo significa que incluso si haces una captura/lanzamiento tus bloques finalmente se ejecutarán).
La razón por la que la reparación de app.config funciona es porque para .NET 1.0 y 1.1 la CLR tenía una captura global que se tragaría Excepciones antes de que no se administraran, lo que, por supuesto, activaría los bloques finalmente correr. Por supuesto, no hay forma de que el marco pueda saber lo suficiente sobre dicha Excepción para manejarlo, por ejemplo, un desbordamiento de pila, por lo que esta es probablemente la forma incorrecta de hacerlo.
El siguiente paso es donde se pone un poco pegajoso, y estoy haciendo suposiciones basadas en lo que dice el artículo aquí.
Si se encuentra en .NET 2.0+ sin el manejo de excepciones heredado entonces su excepción caería en el sistema de manejo de excepciones de Windows (SEH) que parece bastante similar al CLR, en el sentido de que retrocede a través de marcos hasta que no encuentra una captura y luego llama a una serie de eventos llamados el Filtro de excepción no controlada (UEF).Este es un evento al que puede suscribirse, pero solo puede tener UNA cosa suscrita a la vez, de modo que cuando algo se suscribe, Windows le entrega la dirección de la devolución de llamada que estaba allí antes, lo que le permite configurar una cadena de UEF. manejadores - PERO NO TIENEN QUE HONRAR esa dirección, deben llamar ellos mismos a la dirección, pero si uno rompe la cadena, bap, no obtendrá más manejo de errores. Supongo que esto es lo que sucede cuando cancelas el informe de errores de Windows, rompe la cadena UEF, lo que significa que la aplicación se cierra inmediatamente y los bloques finalmente no se ejecutan, sin embargo, si lo dejas correr hasta el final y lo cierras, llamará al próximo UEF en la cadena. .NET habrá registrado uno que es de lo que se llama el AppDomain.UnhandledException (por lo tanto, incluso este evento no está garantizado), que supongo que también es el lugar desde donde se obtienen los bloques finalmente llamados, ya que no puedo ver cómo pasar nunca. de nuevo en el CLR puede ejecutarse un bloque administrado finalmente (el artículo no entra en este bit)
Cuando compilo esto con .NET 4 y lo ejecuto, obtengo el diálogo estándar de Informes de errores de Windows; si cierro esto o hago clic en "No enviar", la consola imprime "en Finalmente". Parece que funciona bien! –
¿Está ejecutando esto desde Visual Studio? Intente ejecutarlo manualmente desde el símbolo del sistema. –
También podría haber una diferencia entre los sistemas 64/32. – Kobi