2010-11-24 35 views
4

Nous avons une application de console .NET qui comporte de nombreux threads de premier plan. Si nous supprimons le processus à l'aide du Gestionnaire des tâches ou si nous publions killjob, tuez à partir de la ligne de commande dans Windows, est-il possible de fermer l'application (en ajoutant du code mangé dans l'application console .net)? fonction étant appelée dire TodoBeforeShutdown() qui dispose des objets, ferme toutes les connexions ouvertes, etcGérer une application .NET pour l'arrêter correctement à la fermeture/à la fermeture

PS - J'ai lu les autres threads et ils ont tous suggéré différentes façons de tuer le processus, plutôt que ma question spécifique, quelle est la meilleure façon de gérer un processus de terminaison, dans le code managé .NET.

Merci d'avance.

Répondre

8

Malheureusement, aucun événement ne peut être levé lorsque vous tuez un processus.
Vous pouvez penser à supprimer un processus comme couper l'alimentation de l'ordinateur, quel que soit le code que vous avez conçu pour être exécuté à l'arrêt du système, si l'ordinateur ne s'éteint pas correctement ou correctement, ce code ne fonctionnera pas . Lorsque vous supprimez un processus à l'aide du Gestionnaire des tâches, il appelle la fonction Win32 TerminateProcess qui force inconditionnellement le processus (y compris tous les threads qu'il possède) à quitter. L'exécution de tous les threads/processus est interrompue et toutes les demandes d'E/S en attente sont annulées. Votre programme est effectivement mort. La fonction TerminateProcess n'appelle pas la séquence d'arrêt fournie par le CLR, de sorte que votre application managée n'aurait même pas la moindre idée de ce qu'elle était en train d'être arrêtée.

Vous suggérez que vous êtes préoccupé par la disposition des objets à chaque fois il est mis fin au processus de votre application, mais il y a deux ou trois choses intéressant de souligner ici:

  • nous nous efforçons toujours de réduire au minimum le montant des dommages pourrait être fait. Jetez vos objets le plus tôt possible lorsque vous en avez fini avec eux. N'attendez pas plus tard. À tout moment, lorsque le processus de votre programme est terminé, vous ne devez garder que le nombre minimum d'objets autour, ce qui laisse moins de possibilités de fuites.

  • Le système d'exploitation nettoie généralement et libère plus de de ces ressources (c'est-à-dire, des poignées, etc.) lors de la résiliation. Enfin, il devrait aller de soi que la terminaison de processus de cette manière est vraiment une condition exceptionnelle - même si certaines ressources fuient, est à prévoir. Vous n'êtes pas censé fermer une application de cette façon, pas plus que vous n'êtes censé tuer les processus système Windows nécessaires (même si vous pouvez le faire en tant qu'administrateur).

Si ceci est votre plan régulier pour arrêter l'application de la console, vous devez trouver un autre plan de.

+0

+1 pour 'vous devez trouver un autre plan' :) – Aamir

+0

Merci pour votre réponse. Je tiens à souligner que cela ne fait pas partie d'un plan, mais plutôt d'une contrainte que nous avons dans l'infrastructure d'ordonnancement par lots de nos sociétés, qui est née de la manière polie de tuer Linux. Cela a ensuite été porté sur Windows et ils ont fini par utiliser kill. – keepsmilinyaar

+0

@keepsmilinyaar: Fait intéressant, la "polie kill" est assez inhabituelle, même dans le monde Unix. La plupart des systèmes d'exploitation basés sur Unix enverront 'SIGKILL' (inconditionnel) plutôt que' SIGTERM' (la méthode polie) pour tuer un processus en réponse à la commande 'killall'. –

2

En bref: Vous ne pouvez pas!
Tuer un processus est exactement le contraire d'une sortie gracieuse.
Si vous exécutez Foreground Threads, l'envoi d'un wm_exit ne fermera pas votre application. Puisque vous avez une application de console, vous pouvez simplement rediriger l'entrée de la console pour envoyer une "sortie" à votre processus.
En outre, je pense que vous pourriez changer l'application pour le service (au lieu d'une application de console), cela vous offrirait exactement ce que vous recherchez -> interface pour sortie gracieuse basée sur les outils/commandes intégrés de Windows.