web-dev-qa-db-fra.com

Comment tuer un fil dans Delphi?

En delphi, une méthode dans TThread est terminée. Il semble qu'un sous-thread ne puisse pas tuer un autre thread en appelant terminate ou free. Par exemple, A (forme principale), B (une unité de filetage), C (une autre forme).

B envoie des données au formulaire principal et C (en appelant syncronize), nous avons essayé de terminer B dans C pendant que B s’exécute en appelant B.terminate. Mais cette méthode ne fonctionne pas et B continue de fonctionner jusqu'à ce qu'elle se termine dans la méthode execute.

S'il vous plaît aider. Merci d'avance.

20
Dylan

Vous devez vérifier Terminate dans le fil pour que cela fonctionne. Par exemple:

procedure TMyThread.Execute;
begin
  while not Terminated do begin
    //Here you do a chunk of your work.
    //It's important to have chunks small enough so that "while not Terminated"
    //gets checked often enough.
  end;
  //Here you finalize everything before thread terminates
end;

Avec cela, vous pouvez appeler

MyThread.Terminate;

Et il se terminera dès qu'il aura fini de traiter une autre partie du travail. Ceci est appelé "fin de thread gracieuse" car le thread lui-même a la possibilité de terminer n'importe quel travail et de préparer la fin.

Il existe une autre méthode, appelée "résiliation forcée". Tu peux appeler:

TerminateThread(MyThread.Handle);

Lorsque vous faites cela, Windows arrête de force toute activité dans le thread. Cela ne nécessite pas de vérifier "Terminated" dans le thread, mais peut potentiellement être extrêmement dangereux, car vous tuez le thread en cours d'opération. Votre application risque de se bloquer après cela.

C'est pourquoi vous n'utilisez jamais TerminateThread tant que vous n'êtes pas absolument sûr d'avoir toutes les conséquences possibles. Actuellement, ce n'est pas le cas, utilisez donc la première méthode.

43
himself

Réellement,

actuellement, la réponse la plus votée à cette question est incorrecte (donc pour les 34 votants supérieurs ...) en ce qui concerne la manière de tuer avec force un thread.

Vous ne faites pas utilisez ThreadId comme paramètre de la procédure TerminateThread. Utiliser ThreadId provoquera très probablement une erreur "Invalid handle" ou, dans le pire des cas, scenerio - tuerait un autre thread.

Vous devriez passer un thread handle _ en tant que paramètre:

TerminateThread(MyThread.Handle);

Vous trouverez plus d’informations sur les différences entre le pseudonyme et l’id du thread ici .

Modifier

Il semble que @himself ait corrigé son erreur après avoir vu ma réponse, ce n'est donc plus pertinent.

14
Wodzu

Terminer ne tue pas un thread; il définit la propriété Terminated pour informer le thread qu'il doit terminer. C'est la responsabilité du fil de surveiller Terminated et de s'arrêter gracieusement.

12
Mason Wheeler

La méthode Terminate n'a pour effet que de définir la propriété Terminated sur true. Vous devez donc manuellement continuer à vérifier cette propriété, puis quitter la méthode thread lorsqu'elle est définie sur true.

3
Timo

Si vous souhaitez mettre fin à un fil de discussion, il est peut-être préférable de créer une autre application et de la tuer si vous pensez que c'est un échec - Windows sera alors rangé après vous.

0
Ed Green