2009-02-09 6 views
5

Nuestra biblioteca de códigos necesita ser notificada cuando la aplicación está saliendo. Por lo tanto, nos hemos suscrito al evento System.Window.Forms.Application.ApplicationExit. Esto funciona muy bien para las aplicaciones Winforms, pero ¿funciona también para otros tipos de aplicaciones, como aplicaciones de consola, servicios y aplicaciones web (como ASP.NET)? El espacio de nombres sugeriría que no es así, y se levanta cuando se llama a Application.Exit() (explícita o implícitamente), lo que puede no ser correcto para llamar a estos otros casos.¿Funciona el evento Application.ApplicationExit para ser notificado de la salida en aplicaciones que no son Winforms?

¿Hay algún otro evento que sería mejor en estos otros casos o que sería más universal (excelente si también funciona para Winforms)? Por ejemplo, ¿hay un evento para cuando se llama al Environment.Exit() (aplicación de la consola)?

He encontrado una mención de un evento de salidos en System.Diagnostic.Process, pero esto parece ser para el control de la salida de otro proceso, y no parece ser recibido por un proceso de sí mismo (por ejemplo, , Process.GetCurrentProcess().Exited += Process_Exited; Process.GetCurrentProcess().EnableRaisingEvents = true;). Pensaría que solo podría surgir después de que el proceso haya salido realmente, así que eso no funcionaría.

Esto es particularmente para .NET 2.0 y C#.

Respuesta

9

Finalmente descubrimos más sobre esto (pero para entonces mi máquina había sido reconstruida y perdí las cookies de mi perfil no registrado aquí, con suerte, permitirá que se publique esta respuesta).

investigación, además, finalmente, unos más eventos que hemos encontrado útiles:

System.Windows.Forms.Application.ThreadExit - Se activa cuando un bucle de mensajes sale System.Windows.Forms.Application.ApplicationExit - Se activa cuando todos los bucles de mensajes de salida System.AppDomain.CurrentDomain.DomainUnload - Se activa cuando un dominio distinto del predeterminado salidas System.AppDomain.CurrentDomain.ProcessExit - Se activa cuando el dominio predeterminado de la aplicación sale de System.AppDomain.CurrentDomain.UnhandledException - Se activa cuando se produce una excepción no detectada, finalizando la aplicación.

Solo uno de los eventos DomainUnload o ProcessExit es posible para un dominio de aplicación dado, dependiendo de si es el dominio predeterminado (nivel superior) para el proceso o si se creó como un subdominio (por ejemplo, en un servidor web) . Si una aplicación no sabe cuál podría ser (como en nuestro caso), necesita suscribirse a ambas si quiere capturar la descarga real por sí mismo. Además, parece que UnhandledException (que a partir de .NET2.0 siempre es fatal) puede evitar los otros dos eventos, por lo que puede tratarse de un tercer caso. Estos tres eventos deberían funcionar para cualquier aplicación .NET.

Existe una advertencia de que el tiempo de ejecución para ProcessExit es limitado (aproximadamente 4 segundos?), Por lo que puede que no sea posible realizar un trabajo "final" exhaustivo en ese controlador de eventos. Debe ser algo que se pueda hacer rápidamente.

Los eventos Application solo se aplican a las aplicaciones de WinForms (sin embargo, sospechamos que no se pueden aplicar en aplicaciones WPF puras). El nombramiento puede ser engañoso porque se nombran por su uso normal más básico que tiene ciertas suposiciones. ThreadExit no se relaciona con el System.Threading.Thread real sino más bien con el bucle de mensaje (Application.Run())) de un subproceso de interfaz de usuario, y ApplicationExit se relaciona de manera similar con la colección de formularios de aplicación en uno o más subprocesos de interfaz de usuario. Normalmente, una vez que vuelve la llamada a Application.Run(), llamada desde el método de entrada de un hilo, el método de entrada concluye rápidamente y el hilo en sí mismo finaliza. Y una vez que todos los subprocesos de la interfaz de usuario han salido, una aplicación de WinForms generalmente se completa y finaliza.

Otro evento de interés es el evento System.Windows.Forms.Application.ThreadException. Se puede configurar un bucle de mensaje de Windows para detectar las excepciones que ocurren al manejar un mensaje y enviar este evento en lugar de dejar que sean excepciones no detectadas (y por lo tanto fatales). La captura de estas excepciones permite que el bucle de mensajes (y esa cadena de interfaz de usuario) continúe ejecutándose (después de cancelar el controlador de mensajes actual). Solo puede haber un suscriptor para este evento en cualquier momento para un hilo dado (las suscripciones sobrescriben a cualquier suscriptor anterior) y debe configurarse antes de que se cree y se suscriba cualquier Formulario antes de ingresar al ciclo de mensajes. Consulte la ayuda de MSDN para este evento y System.Windows.Forms.Applicaton.SetUnhandledExceptionMode() para obtener más información.

Cuestiones relacionadas