Tenemos una aplicación WPF donde partes de ella pueden generar excepciones en tiempo de ejecución. Me gustaría detectar globalmente cualquier excepción no controlada y registrarla, pero de lo contrario continuar con la ejecución del programa como si nada sucediera (algo así como VB On Error Resume Next
).
¿Es esto posible en C #? Y si es así, ¿dónde exactamente necesitaría poner el código de manejo de excepciones?
Actualmente no puedo ver ningún punto único en el que pueda ajustar un try
/ catch
alrededor y que atrape todas las excepciones que puedan ocurrir. Y aun así, habría dejado todo lo que se ha ejecutado debido a la captura. ¿O estoy pensando en direcciones horriblemente incorrectas aquí?
ETA: Porque muchas personas a continuación lo señalaron: la aplicación no es para controlar plantas de energía nuclear. Si se bloquea, no es un gran problema, pero las excepciones aleatorias que están relacionadas principalmente con la interfaz de usuario son una molestia en el contexto en el que se usarían. Hubo (y probablemente todavía hay) algunos de ellos, ya que utiliza una arquitectura de complemento y puede ser extendido por otros (también estudiantes en ese caso; por lo tanto, no hay desarrolladores experimentados que puedan escribir código completamente libre de errores).
En cuanto a las excepciones que quedan atrapadas: las registro en un archivo de registro, incluida la traza completa de la pila. Ese fue el objetivo de ese ejercicio. Solo para contrarrestar a esas personas que estaban tomando mi analogía con el OERN de VB demasiado literalmente.
Sé que ignorar ciegamente ciertas clases de errores es peligroso y podría corromper mi instancia de aplicación. Como se dijo antes, este programa no es de misión crítica para nadie. Nadie en su sano juicio apostaría por la supervivencia de la civilización humana. Es simplemente una pequeña herramienta para probar ciertos enfoques de diseño wrt. Ingeniería de software.
Para el uso inmediato de la aplicación, no hay muchas cosas que puedan suceder en una excepción:
- Sin manejo de excepciones: diálogo de error y salida de la aplicación. El experimento tiene que repetirse, aunque probablemente con otro sujeto. No se han registrado errores, lo cual es lamentable.
- Manejo genérico de excepciones: error benigno atrapado, sin daño. Este debería ser el caso común a juzgar por todos los errores que estábamos viendo durante el desarrollo. Ignorar este tipo de errores no debería tener consecuencias inmediatas; Las estructuras de datos centrales se prueban lo suficientemente bien como para sobrevivir fácilmente a esto.
- Manejo de excepciones genéricas: error grave atrapado, posiblemente bloqueado en un momento posterior. Esto puede suceder raramente. Nunca lo hemos visto hasta ahora. El error se registra de todos modos y un bloqueo puede ser inevitable. Entonces, esto es conceptualmente similar al primer caso. Excepto que tenemos un seguimiento de pila. Y en la mayoría de los casos, el usuario ni siquiera lo notará.
En cuanto a los datos del experimento generados por el programa: un error grave en el peor de los casos solo provocaría que no se registraran datos. Los cambios sutiles que cambian el resultado del experimento muy ligeramente son bastante improbables. E incluso en ese caso, si los resultados parecen dudosos, se registra el error; aún se puede descartar ese punto de datos si es un valor atípico total.
Para resumir: Sí, me considero todavía al menos parcialmente cuerdo y no considero una rutina de manejo de excepciones global que deje el programa en ejecución necesariamente necesariamente malo. Como se dijo dos veces antes, tal decisión podría ser válida, dependiendo de la aplicación. En este caso se juzgó una decisión válida y no una mierda total y absoluta. Para cualquier otra aplicación, esa decisión podría verse diferente. Pero, por favor, no me acusen a mí ni a las otras personas que trabajaron en ese proyecto para hacer explotar el mundo potencialmente solo porque estamos ignorando errores.
Nota al margen: hay exactamente un usuario para esa aplicación. No es algo como Windows u Office que usan millones donde el costo de tener excepciones para el usuario sería muy diferente en primer lugar.
On Error Resume Next
no es posible en C #. Después de unException
(C # no tiene "errores") no puede simplemente continuar con la siguiente instrucción: la ejecución continuará en uncatch
bloque, o en uno de los controladores de eventos que se describen en las respuestas a continuación.Respuestas:
Usa el
Application.DispatcherUnhandledException Event
. Vea esta pregunta para un resumen (vea la respuesta de Drew Noakes ).Tenga en cuenta que todavía habrá excepciones que impiden la reanudación exitosa de su aplicación, como después de un desbordamiento de pila, memoria agotada o pérdida de conectividad de red mientras intenta guardar en la base de datos.
fuente
Código de ejemplo que usa NLog que capturará excepciones lanzadas desde todos los subprocesos en el dominio de aplicación , desde el subproceso del despachador de la interfaz de usuario y desde las funciones asíncronas :
App.xaml.cs:
fuente
UnhandledException
controlador no la estaba captando. Tuve que mirar el Visor de registro de eventos de Windows para encontrar lo que estaba sucediendo ...e.Handled = true;
en elUnhandledException
que la aplicación no se colgará en la interfaz de usuario ExcepcionesAppDomain.UnhandledException Event
fuente
Además de lo que otros mencionaron aquí, tenga en cuenta que la combinación de
Application.DispatcherUnhandledException
(y sus similares ) conen el
app.config
evitará que la excepción de subprocesos secundarios cierre la aplicación.fuente
Aquí hay un ejemplo completo usando
NLog
fuente
Como "¿VB's en error reanudar después?" Eso suena un poco aterrador. La primera recomendación es no hacerlo. La segunda recomendación es no hacerlo y no pensar en ello. Necesita aislar mejor sus fallas. En cuanto a cómo abordar este problema, depende de cómo esté estructurado su código. Si está utilizando un patrón como MVC o similar, entonces esto no debería ser demasiado difícil y definitivamente no requeriría una deglución de excepción global. En segundo lugar, busque una buena biblioteca de registro como log4net o use el rastreo. Necesitaríamos conocer más detalles, como qué tipo de excepciones está hablando y qué partes de su aplicación pueden generar excepciones.
fuente