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?
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.
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.
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.
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()
.
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 [~ # ~]
ThreadAborts ne se produira pas à l'intérieur d'un bloc finally ou entre BeginCriticalRegion et EndCriticalRegion
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); }});
Parce que vous pouvez attraper le ThreadAbortException
et appeler Thread.ResetAbort
à l'intérieur du gestionnaire.
OT: Pour une approche globale, concurrente, agnostique sur les langues, discutable et drôle, voir Verity Stob !