web-dev-qa-db-fra.com

Terminaison de thread C # et Thread.Abort ()

Dans MSDN, la description de la méthode Thread.Abort () indique: "L'appel de cette méthode généralement met fin au thread."

Pourquoi pas toujours?

Dans quels cas il ne termine pas le fil?

Existe-t-il une autre possibilité de terminer les threads?

82
user101375

Thread.Abort() injecte un ThreadAbortException sur le thread. Le thread peut annuler la demande en appelant Thread.ResetAbort(). En outre, certaines parties du code, telles que le bloc finally, seront exécutées avant le traitement de l'exception. Si pour une raison quelconque le thread est bloqué dans un tel bloc, l'exception ne sera jamais levée sur le thread.

Comme l'appelant a très peu de contrôle sur l'état du thread lorsqu'il appelle Abort(), il est généralement déconseillé de le faire. Transmettez plutôt un message au thread demandant la résiliation.

57
Brian Rasmussen

Dans quels cas il ne termine pas le fil?

Cette question est un doublon.

Quel est le problème avec l'utilisation de Thread.Abort ()

Existe-t-il une autre possibilité de terminer les threads?

Oui. Votre problème est que vous ne devriez jamais démarrer un fil que vous ne pouvez pas dire poliment d'arrêter, et il s'arrête rapidement. Si vous êtes dans une situation où vous devez démarrer un fil qui pourrait être (1) difficile à arrêter, (2) bogué, ou pire (3) hostile à l'utilisateur, la bonne chose à faire est de faire un nouveau processus, démarrez le fil dans le nouveau processus, puis terminez le processus lorsque vous souhaitez que le fil se désactive. La seule chose qui puisse garantir une terminaison sûre d'un thread qui ne coopère pas est le système d'exploitation prenant en charge l'intégralité de son processus.

Voir ma réponse excessivement longue à cette question pour plus de détails:

tilisation de l'instruction de verrouillage dans une boucle en C #

Le bit pertinent est le bit à la fin où je discute des considérations concernant le temps que vous devez attendre pour qu'un thread se tue avant de l'abandonner.

52
Eric Lippert

Pourquoi pas toujours? Dans quels cas ne termine-t-il pas le fil?

Pour commencer, un thread peut attraper un ThreadAbortException et annuler sa propre terminaison. Ou bien, vous pourriez effectuer un calcul qui prend une éternité pendant que vous essayez de l'abandonner. De ce fait, le moteur d'exécution ne peut pas garantir que le thread se terminera toujours une fois que vous l'avez demandé.

ThreadAbortException a plus:

Lorsqu'un appel est fait à la méthode Abort pour détruire un thread, le common language runtime lève une exception ThreadAbortException. ThreadAbortException est une exception spéciale qui peut être interceptée, mais elle sera automatiquement levée à la fin du bloc catch. Lorsque cette exception est déclenchée, le moteur d'exécution exécute tous les blocs finally avant de terminer le thread. Le thread pouvant effectuer un calcul sans limite dans les blocs finally, ou appeler Thread.ResetAbort() pour annuler l'abandon, rien ne garantit que le thread se terminera jamais.

Vous n'avez pas besoin de Abort() un thread manuellement. Le CLR fera tout le sale boulot pour vous si vous laissez simplement la méthode dans le thread revenir; cela mettra fin au fil normalement.

17
John Feminella

FileStream.Read() à un canal nommé qui ne reçoit actuellement rien (les blocs d'appel lus en attendant les données entrantes) ne répondra pas à Thread.Abort(). Il reste dans l'appel Read().

6
jovain

Que se passe-t-il si un thread détient un verrou et est abandonné/tué? Les ressources restent bloquées

Cela fonctionne bien lorsqu'un appel de fil s'abandonne mais pas par un autre fil. Abandonner, met fin de force au thread affecté même s'il n'a pas terminé sa tâche et ne fournit aucune possibilité de nettoyage des ressources

référence [~ # ~] msdn [~ # ~]


voir: Meilleures pratiques en matière de threading géré

5
Asad Butt

ThreadAborts ne se produira pas à l'intérieur d'un bloc finally ou entre BeginCriticalRegion et EndCriticalRegion

4
Rob Fonseca-Ensor

Je n'arrive pas à abandonner un fil bloqué dans une boucle:

//immortal
Thread th1 = new Thread(() => { while (true) {}});

Je peux cependant abandonner le fil si dort pendant la boucle:

//mortal
Thread th2 = new Thread(() => { while (true) { Thread.Sleep(1000); }});
4
Colin

Parce que vous pouvez attraper le ThreadAbortException et appeler Thread.ResetAbort à l'intérieur du gestionnaire.

3
erikkallen

OT: Pour une approche globale, concurrente, agnostique sur les langues, discutable et drôle, voir Verity Stob !

0
Pontus Gagge