Votre fil Execute
doit régulièrement vérifier l'état de l'objet de la méthode Terminated
propriété. Et si c'est True
puis le fil Execute
doit se terminer.
Donc, un typique Execute
pourrait ressembler à ceci :
procedure TMyThread.Execute;
begin
while not Terminated do
DoNextPieceOfWork
end;
On dirait que votre fil a sa propre FActive
qui effectue la même tâche. Le problème avec cela est que TThread
n'est pas au courant. Donc vous devriez vous débarrasser FActive
et utiliser plutôt le mécanisme intégré.
Lorsque vous appelez Free
sur le fil, il appellera Terminate
. Cela met Terminated
à être True
. Ensuite, il attend que la méthode du fil se termine. Cela se produira parce que votre thread a remarqué que Terminated
es True
et démissionne. Ensuite, le destructeur du fil peut continuer et terminer le travail de rangement du fil.
En regardant le code dans votre réponse, il serait mieux écrit de faire usage de l'existant Terminate
mécanisme.
type
TMyThread = class(TThread)
private
FTerminateEvent: TEvent;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create(ACreateSuspended: Boolean);
destructor Destroy; override;
end;
constructor TMyThread.Create(ACreateSuspended: Boolean);
begin
inherited Create(ACreateSuspended);
FTerminateEvent := TEvent.Create(nil, True, False, '');
end;
destructor TMyThread.Destroy;
begin
inherited;
FTerminateEvent.Free;
end;
procedure TMyThread.TerminatedSet;
begin
FTerminateEvent.SetEvent;
end;
procedure TMyThread.Execute;
begin
while not Terminated do
begin
// do somthing interesting!
FTerminateEvent.WaitFor(5000);
end;
end;
Maintenant, il n'y a pas besoin d'une Stop
méthode. Vous pouvez simplement appeler Free
sur le fil. Puis Terminate
est appelé. Et puis TerminatedSet
est appelé. Puis l'événement est signalé. Puis Execute
se termine. Et puis le fil peut disparaître.
Cela dit, j'ai du mal à imaginer un scénario dans lequel un délai de 5000 ms serait la meilleure approche. Je ne sais pas pourquoi vous faites cela, mais je suppose que vous essayez d'étrangler le thread pour qu'il ne s'exécute pas chaud . Vous voulez éviter une boucle occupée. C'est admirable, mais l'utilisation d'un délai d'attente fixe n'est pas la bonne façon de procéder. La méthode consiste à attendre un événement de synchronisation, généralement un événement. Ensuite, lorsqu'il y a plus de travail à faire, l'événement est signalé et votre thread se réveille.