96 votes

Capture console exit C #

J'ai une application console qui contient pas mal de threads. Il y a des threads que le suivi de certaines conditions et de mettre fin au programme si elles sont vraies. Cette résiliation peut se produire à tout moment.

J'ai besoin d'un événement qui peut être déclenché lorsque le programme est en cours de fermeture, de sorte que je peux nettoyage de tous les autres threads et de fermer tous les descripteurs de fichiers et connexions correctement. Je ne sais pas si il y en a un déjà construit dans l' .NET framework, donc je pose la question avant d'écrire mon propre.

Je me demandais si il y avait un événement le long des lignes de:

MyConsoleProgram.OnExit += CleanupBeforeExit;

100voto

flq Points 11937

Je ne suis pas sûr de l'endroit où j'ai trouvé le code sur le web, mais je l'ai trouvé dans un de mes anciens projets. Cela vous permettra de faire le nettoyage de code dans votre console, par exemple, lorsqu'il est brusquement fermé ou en raison d'un arrêt...

[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

private delegate bool EventHandler(CtrlType sig);
static EventHandler _handler;

enum CtrlType
{
  CTRL_C_EVENT = 0,
  CTRL_BREAK_EVENT = 1,
  CTRL_CLOSE_EVENT = 2,
  CTRL_LOGOFF_EVENT = 5,
  CTRL_SHUTDOWN_EVENT = 6
}

private static bool Handler(CtrlType sig)
{
  switch (sig)
  {
      case CtrlType.CTRL_C_EVENT:
      case CtrlType.CTRL_LOGOFF_EVENT:
      case CtrlType.CTRL_SHUTDOWN_EVENT:
      case CtrlType.CTRL_CLOSE_EVENT:
      default:
          return false;
  }
}


static void Main(string[] args)
{
  // Some biolerplate to react to close window event
  _handler += new EventHandler(Handler);
  SetConsoleCtrlHandler(_handler, true);
  ...
}

Mise à jour

Pour ceux qui ne vérifiant pas les commentaires, il semble que cette solution ne permet pas de bien travailler (ou à tous) sur Windows 7. Le fil de discussion suivant les pourparlers à ce sujet: http://social.msdn.microsoft.com/Forums/en/windowscompatibility/thread/abf09824-4e4c-4f2c-ae1e-5981f06c9c6e

30voto

JJ_Coder4Hire Points 301

Exemple de travail complet, fonctionne avec ctrl-c, ferme les fenêtres avec X et kill:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace TestTrapCtrlC {
    public class Program {
        static bool exitSystem = false;

        #region Trap application termination
        [DllImport("Kernel32")]
        private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);

        private delegate bool EventHandler(CtrlType sig);
        static EventHandler _handler;

        enum CtrlType {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT = 1,
            CTRL_CLOSE_EVENT = 2,
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT = 6
        }

        private static bool Handler(CtrlType sig) {
            Console.WriteLine("Exiting system due to external CTRL-C, or process kill, or shutdown");

            //do your cleanup here
            Thread.Sleep(5000); //simulate some cleanup delay

            Console.WriteLine("Cleanup complete");

            //allow main to run off
            exitSystem = true;

            //shutdown right away so there are no lingering threads
            Environment.Exit(-1);

            return true;
        }
        #endregion

        static void Main(string[] args) {
            // Some biolerplate to react to close window event, CTRL-C, kill, etc
            _handler += new EventHandler(Handler);
            SetConsoleCtrlHandler(_handler, true);

            //start your multi threaded program here
            Program p = new Program();
            p.Start();

            //hold the console so it doesn't run off the end
            while (!exitSystem) {
                Thread.Sleep(500);
            }
        }

        public void Start() {
            // start a thread and start doing some processing
            Console.WriteLine("Thread started, processing..");
        }
    }
}
 

7voto

jmservera Points 3239

Vérifiez aussi:

 AppDomain.CurrentDomain.ProcessExit
 

4voto

Rob Points 1138

On dirait que les threads mettent directement fin à l'application? Peut-être serait-il préférable d’avoir un thread qui indique au thread principal que l’application doit être terminée.

À la réception de ce signal, le thread principal peut éteindre proprement les autres threads et enfin se fermer.

3voto

Rob Prouse Points 9193

Il y a pour les applications WinForms;

 Application.ApplicationExit += CleanupBeforeExit;
 

Pour les applications de la console, essayez

 AppDomain.CurrentDomain.DomainUnload += CleanupBeforeExit;
 

Mais je ne sais pas à quel moment cela s'appelle ou si cela fonctionnera à partir du domaine actuel. Je suppose que non.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X