J'ai créé un fil exécutant une certaine méthode. Mais parfois, je voudrais tuer le fil même s'il fonctionne toujours. Comment puis-je faire ceci? J'ai essayé Thread.Abort () mais il affiche une boîte de message disant "Thread aborted". Que devrais-je faire?
Thread.Abort()
!Thread.Abort
Est dangereux. Au lieu de cela, vous devez coopérer avec le fil afin qu'il puisse être arrêté pacifiquement. Le thread doit être conçu de manière à pouvoir lui dire de se tuer, par exemple en ayant un indicateur booléen keepGoing
que vous définissez sur false lorsque vous voulez que le thread s'arrête. Le fil aurait alors quelque chose comme
while (keepGoing)
{
/* Do work. */
}
Si le thread peut bloquer dans un Sleep
ou Wait
alors vous pouvez le séparer de ces fonctions en appelant Thread.Interrupt()
. Le thread doit alors être préparé pour gérer un ThreadInterruptedException
:
try
{
while (keepGoing)
{
/* Do work. */
}
}
catch (ThreadInterruptedException exception)
{
/* Clean up. */
}
Vous ne devriez vraiment appeler Abort () qu'en dernier recours. Vous pouvez utiliser une variable pour synchroniser ce fil à la place:
volatile bool shutdown = false;
void RunThread()
{
while (!shutdown)
{
...
}
}
void StopThread()
{
shutdown = true;
}
Cela permet à votre thread de terminer proprement ce qu'il faisait, laissant votre application dans un bon état connu.
Le moyen le plus correct et le plus sûr pour les threads est d'utiliser un WaitHandle pour signaler au thread quand il est censé s'arrêter. J'utilise principalement ManualResetEvent.
Dans votre fil, vous pouvez avoir:
private void RunThread()
{
while(!this.flag.WaitOne(TimeSpan.FromMilliseconds(100)))
{
// ...
}
}
où this.flag
est une instance de ManualResetEvent. Cela signifie que vous pouvez appeler this.flag.Set()
depuis l'extérieur du thread pour arrêter la boucle.
La méthode WaitOne ne renvoie true que lorsque l'indicateur est défini. Sinon, il expirera après le délai spécifié (100 ms dans l'exemple) et le thread s'exécutera à nouveau dans la boucle.
Ce n'est pas une bonne idée de tuer un fil. Il vaut mieux signaler qu'il doit s'arrêter et se terminer avec élégance. Il existe différentes façons de procéder.
Thread.Interrupt
pour le pousser s'il est bloqué.WaitHandle
pour envoyer un signal.Il n'est pas nécessaire pour moi de ressasser la façon dont chaque méthode peut être utilisée puisque je l'ai déjà fait dans cette réponse .
L'abandon d'un thread est une très mauvaise idée, car vous ne pouvez pas déterminer ce que le thread faisait au moment de l'interruption.
Au lieu de cela, disposez d'une propriété que le thread peut vérifier et que votre code externe peut définir. Laissez le thread vérifier cette propriété booléenne lorsqu'il se trouve dans un endroit sûr pour quitter.
J'accepte Jon B
volatile bool shutdown = false;
void RunThread()
{
try
{
while (!shutdown)
{
/* Do work. */
}
}
catch (ThreadAbortException exception)
{
/* Clean up. */
}
}
void StopThread()
{
shutdown = true;
}
Il y a aussi des exemples de tuer des threads dans ma classe WebServer ...
https://net7ntcip.codeplex.com/SourceControl/changeset/view/89621#1752948
Je dirais que l'abandon est correct, comprenez simplement quelles sont les ramifications ... tant que vous indiquez l'état avant qu'une tâche de longue durée ne fonctionne, mais des indicateurs sont requis tels que (ShouldStop ou ActionBranch, etc.)
Consultez-le pour des exemples!