Considérez une application console qui démarre certains services dans un thread distinct. Tout ce qu'il faut faire est d'attendre que l'utilisateur appuie sur Ctrl + C pour l'arrêter.
Laquelle des propositions suivantes est la meilleure façon de procéder?
static ManualResetEvent _quitEvent = new ManualResetEvent(false);
static void Main() {
Console.CancelKeyPress += (sender, eArgs) => {
_quitEvent.Set();
eArgs.Cancel = true;
};
// kick off asynchronous stuff
_quitEvent.WaitOne();
// cleanup/shutdown and quit
}
Ou ceci, en utilisant Thread.Sleep (1):
static bool _quitFlag = false;
static void Main() {
Console.CancelKeyPress += delegate {
_quitFlag = true;
};
// kick off asynchronous stuff
while (!_quitFlag) {
Thread.Sleep(1);
}
// cleanup/shutdown and quit
}
c#
multithreading
sleep
manualresetevent
intoOrbit
la source
la source
bool
n'est pas déclaré commevolatile
, il y a la possibilité définitive que les lectures ultérieures_quitFlag
dans lawhile
boucle soient optimisées, conduisant à une boucle infinie.Alternativement, une solution plus simple est simplement:
la source
Vous pouvez le faire (et supprimer le
CancelKeyPress
gestionnaire d'événements):Je ne sais pas si c'est mieux, mais je n'aime pas l'idée d'appeler
Thread.Sleep
en boucle .. Je pense que c'est plus propre de bloquer les entrées de l'utilisateur.la source
Je préfère utiliser l' application.
à partir de la documentation:
la source
On dirait que vous rendez les choses plus difficiles que nécessaire. Pourquoi pas juste
Join
le fil après que vous lui avez signalé de s'arrêter?la source
Il est également possible de bloquer le thread / programme en fonction d'un jeton d'annulation.
WaitHandle est signalé lorsque le jeton est annulé.
J'ai vu cette technique utilisée par Microsoft.Azure.WebJobs.JobHost, où le jeton provient d'une source de jeton d'annulation de WebJobsShutdownWatcher (un observateur de fichiers qui met fin au travail).
Cela donne un certain contrôle sur la fin du programme.
la source
CTL+C
parce qu'elle effectue une opération de longue durée, ou est un démon, qui devrait également arrêter ses threads de travail. Vous feriez cela avec un CancelToken et cette réponse tire parti d'unWaitHandle
qui existerait déjà, plutôt que d'en créer un nouveau.Des deux, le premier est meilleur
parce que dans le second, le thread se réveille toutes les millisecondes sera transformé en interruption du système d'exploitation qui coûte cher
la source
Console
méthodes si vous n'avez pas de console attachée (parce que, par exemple, le programme est démarré par un service)Vous devez le faire comme vous le feriez si vous programmiez un service Windows. Vous n'utiliseriez jamais une instruction while à la place, vous utiliseriez un délégué. WaitOne () est généralement utilisé en attendant que les threads se débarrassent - Thread.Sleep () - n'est pas conseillé - Avez-vous pensé à utiliser System.Timers.Timer en utilisant cet événement pour vérifier l'événement d'arrêt?
la source