Tengo una aplicación de consola que contiene bastantes hilos. Hay hilos que monitorean ciertas condiciones y terminan el programa si son verdaderas. Esta terminación puede ocurrir en cualquier momento.
Necesito un evento que pueda activarse cuando el programa se está cerrando para poder limpiar todos los demás subprocesos y cerrar todos los identificadores de archivos y conexiones correctamente. No estoy seguro de si ya hay uno integrado en el marco .NET, así que pregunto antes de escribir el mío.
Me preguntaba si hubo un evento como:
MyConsoleProgram.OnExit += CleanupBeforeExit;
Respuestas:
No estoy seguro de dónde encontré el código en la web, pero lo encontré ahora en uno de mis proyectos anteriores. Esto le permitirá hacer un código de limpieza en su consola, por ejemplo, cuando se cierra abruptamente o debido a un apagado ...
Actualizar
Para aquellos que no revisan los comentarios, parece que esta solución en particular no funciona bien (o en absoluto) en Windows 7 . El siguiente hilo habla de esto
fuente
bool Handler()
debereturn false;
(no devuelve nada en el código) para que funcione. Si devuelve verdadero, Windows muestra el cuadro de diálogo "Terminar proceso ahora". = DEjemplo de trabajo completo, funciona con ctrl-c, cerrando las ventanas con X y kill:
fuente
Handler
excepto por elreturn true
y un ciclo while para contar los segundos. La aplicación continúa ejecutándose en ctrl-c pero se cierra después de 5 segundos cuando se cierra con la X.Handler
método {usando Win10, .NET Framework 4.6.1}Compruebe también:
fuente
Console.CancelKeyPress
, elProcessExit
evento realmente se generó después de laCancelKeyPress
ejecución de todos los controladores de eventos.Tuve un problema similar, solo la aplicación de mi consola se ejecutaría en un bucle infinito con una declaración preventiva en el medio. Aquí está mi solución:
fuente
¿Parece que los hilos terminan directamente la aplicación? Quizás sería mejor tener una señal de subproceso en el subproceso principal para decir que la aplicación debe terminarse.
Al recibir esta señal, el hilo principal puede cerrar limpiamente los otros hilos y finalmente cerrarse.
fuente
La respuesta de ZeroKelvin funciona en la aplicación de consola Windows 10 x64, .NET 4.6. Para aquellos que no necesitan lidiar con la enumeración CtrlType, aquí hay una forma realmente simple de conectarse al cierre del marco:
Devolver FALSE desde el manejador le dice al marco que no estamos "manejando" la señal de control, y se usa la siguiente función de manejador en la lista de manejadores para este proceso. Si ninguno de los controladores devuelve VERDADERO, se llama al controlador predeterminado.
Tenga en cuenta que cuando el usuario realiza un cierre de sesión o apagado, Windows no llama a la devolución de llamada, sino que finaliza inmediatamente.
fuente
Hay para aplicaciones WinForms;
Para aplicaciones de consola, intente
Pero no estoy seguro de en qué momento se llama o si funcionará desde el dominio actual. Sospecho que no.
fuente
Visual Studio 2015 + Windows 10
Código:
fuente
El enlace mencionado anteriormente por Charle B en un comentario a flq
En el fondo dice:
En algún otro lugar del hilo, se sugiere crear una ventana oculta. Así que creo un winform y en la carga lo conecté a la consola y ejecuté Main original. Y luego SetConsoleCtrlHandle funciona bien (se llama a SetConsoleCtrlHandle como lo sugiere flq)
fuente
AllocConsole
como en su ejemplo) para mostrar información adicional. El problema es que toda la aplicación (todas las ventanas) se cierra si el usuario hace clic en la (X) en la ventana de la consola. LasSetConsoleCtrlHandler
obras, pero las paradas de aplicaciones de todos modos antes de cualquier código en el controlador ejecuta (I ver los puntos de interrupción despedidos y en ese momento se detiene la aplicación).Para aquellos interesados en VB.net. (Busqué en Internet y no pude encontrar un equivalente) Aquí está traducido a vb.net.
fuente