2008-08-04 27 views
22

Estoy manteniendo una aplicación .NET 1.1 y una de las cosas que me han encomendado es asegurarme de que el usuario no vea ninguna notificación de error hostil.Controlador de excepciones no administradas en .NET 1.1

He agregado controladores a Application.ThreadException y AppDomain.CurrentDomain.UnhandledException, que se llaman. Mi problema es que el cuadro de diálogo de error CLR estándar todavía se muestra (antes de que se llame al controlador de excepciones).

Jeff habla sobre este problema en su blog here y here. Pero no hay solución. Entonces, ¿cuál es la forma estándar en .NET 1.1 para manejar excepciones no detectadas y mostrar un cuadro de diálogo amigable?

La respuesta de Jeff se marcó como la respuesta correcta, porque el enlace que proporcionó tiene la información más completa sobre cómo hacer lo que se requiere.

Respuesta

11

Oh, en Windows Forms definitivamente deberías poder hacer que funcione. Lo único que debes vigilar es que las cosas sucedan en diferentes hilos.

Tengo un viejo artículo del Proyecto Código aquí lo que debería ayudar:

User Friendly Exception Handling

3

¿Se trata de una aplicación de consola o una aplicación de Windows Forms? Si se trata de una aplicación de consola .NET 1.1 esto es, por desgracia, por diseño - es confirmada por un dev MSFT en el second blog post you referenced:

Por cierto, en mi máquina el ejemplo 1.1 a partir de MSDN tiene el resultado esperado; es solo que la segunda línea no aparece hasta después de haber adjuntado un depurador (o no). En v2 hemos cambiado las cosas para que el evento UnhandledException se active antes de que se adjunte el depurador, que parece ser lo que la mayoría de la gente espera.

Suena como .NET 2.0 hace esto mejor (gracias a Dios), pero, sinceramente, nunca tuve tiempo de volver atrás y comprobar.

1

Es una aplicación de Windows Forms. Las excepciones detectadas por Application.ThreadException funcionan bien y no obtengo el feo cuadro de excepción .NET (OK para terminar, Cancelar para depurar? ¿A quién se le ocurrió eso?).

Recibí algunas excepciones que no fueron detectadas por eso y terminé yendo al evento AppDomain.UnhandledException que causaba problemas. Creo que capté la mayoría de esas excepciones, y ahora las mostraré en nuestro bonito cuadro de error.

Así que tendré que esperar que no haya otras circunstancias que hagan que las excepciones no sean detectadas por el controlador Application.ThreadException.

4

AppDomain.UnhandledException es un evento , no un gestor de excepciones global. Esto significa que, en el momento en que se produce, su aplicación ya está en camino a la fuga, y no hay nada que pueda hacer al respecto, a excepción de la limpieza y el registro de errores.

Lo que sucedió detrás de escena es esto: el marco detectó la excepción, subió la pila de llamadas hasta la parte superior, no encontró controladores que se recuperaran del error, por lo que no pudo determinar si era seguro continuar la ejecución .Entonces, comenzó la secuencia de apagado y activó este evento como una cortesía para que pueda presentar sus respetos a su proceso ya condenado. Esto sucede cuando una excepción no se deja en el hilo principal.

No existe una solución de punto único para este tipo de error. Debe colocar un controlador de excepción real (un bloque de catch) en sentido ascendente de todos los lugares donde se produce este error y reenviarlo a (por ejemplo) un método/clase de controlador global que determinará si es seguro simplemente informar y continuar, en función de tipo de excepción y/o contenido.

Editar: Es posible desactivar (= piratear) el mecanismo de notificación de errores incorporado en Windows, por lo que el diálogo obligatorio de "bloqueo y grabación" no se muestra cuando la aplicación se apaga. Sin embargo, esto se hace efectivo para todas las aplicaciones en el sistema, no solo las suyas.

5

no controlada comportamiento de excepción en un 1.x .NET Windows Forms depende de:

  • El tipo de hilo que lanzó la excepción
  • si ocurrió durante el procesamiento de mensajes ventana
  • Ya sea un depurador se adjuntó al proceso
  • el ajuste
  • la bandera jitDebugging en app.config
  • registro DbgJitDebugLaunchSetting 210
  • Ya sea que pesaban más que las de Windows Forms gestor de excepciones
  • Ya sea que usted manejó evento de excepción del CLR
  • La fase de la luna

El comportamiento predeterminado de excepciones no controladas es:

  • Si el se produce una excepción en el hilo principal al bombear mensajes de ventana, es interceptado por el manejador de excepciones de Windows Forms.
  • Si la excepción ocurre en el hilo principal al bombear mensajes de ventana, terminará el proceso de la aplicación a menos que sea interceptado por el manejador de excepciones de Windows Forms.
  • Si la excepción se produce en un hilo manual, de subprocesos o de finalizador, se lo traga el CLR.

Los puntos de contacto para una excepción no controlada son:

  • Windows Forms gestor de excepciones.
  • El modificador de registro JIT-debug DbgJitDebugLaunchSetting.
  • El evento de excepción CLR no controlada.

El formulario de Windows integrada en el manejo de excepciones hace lo siguiente de forma predeterminada:

  • detecta una excepción no controlada cuando:
    • excepción es el hilo principal y ningún depurador asociado.
    • se produce una excepción durante el procesamiento del mensaje de la ventana.
    • jitDebugging = false en App.Config.
  • Muestra el diálogo al usuario y evita la finalización de la aplicación.

Puede desactivar este último comportamiento configurando jitDebugging = true en App.Config. Pero recuerda que esta puede ser tu última oportunidad para detener la finalización de la aplicación. Así que el siguiente paso para capturar una excepción no controlada es el registro para el evento Application.ThreadException, por ejemplo .:

Application.ThreadException += new 
Threading.ThreadExceptionHandler(CatchFormsExceptions); 

observe la configuración DbgJitDebugLaunchSetting en HKEY_LOCAL_MACHINE \ Software.NetFramework registro. Esto tiene uno de los tres valores que conozco:

  • 0: muestra el cuadro de diálogo del usuario que pregunta "depurar o terminar".
  • 1: permite la excepción a través de CLR para tratar.
  • 2: inicia el depurador especificado en la clave de registro DbgManagedDebugger.

En Visual Studio, vaya al menú HerramientasOpcionesdepuraciónJIT a establecer esta clave a 0 ó 2. Sin embargo, un valor de 1 es generalmente mejor con el usuario final de máquina. Tenga en cuenta que esta clave de registro se actúa antes del evento de excepción CLR no controlada.

Este último evento es su última oportunidad para registrar una excepción no controlada. Se dispara antes de que se hayan ejecutado los bloques Finally. Puede interceptar este evento de la siguiente manera:

AppDomain.CurrentDomain.UnhandledException += new 
System.UnhandledExceptionEventHandler(CatchClrExceptions); 
Cuestiones relacionadas