Comment résilier anonyme threads en Delphi sur demande à proximité?

J'ai une application Delphi, qui engendre le 6 anonyme threads sur un TTimer.Événement OnTimer.

Si je ferme l'application à partir du bouton X dans la barre de titre de Violation d'Accès à l'adresse $C0000005 est soulevé et FastMM rapports de fuite TAnonymousThread objets.

Qui est le meilleur moyen de anonyme gratuit threads en Delphi créé au sein événement OnTimer avec TThread.CreateAnonymousThread() la méthode?

SOLUTION qui a fonctionné pour moi:

Créé une enveloppe anonyme des threads qui met fin à être Libre-ed.

type
TAnonumousThreadPool = class sealed(TObject)
strict private
FThreadList: TThreadList;
procedure TerminateRunningThreads;
procedure AnonumousThreadTerminate(Sender: TObject);
public
destructor Destroy; override; final;
procedure Start(const Procs: array of TProc);
end;
{ TAnonumousThreadPool }
procedure TAnonumousThreadPool.Start(const Procs: array of TProc);
var
T: TThread;
n: Integer;
begin
TerminateRunningThreads;
FThreadList := TThreadList.Create;
FThreadList.Duplicates := TDuplicates.dupError;
for n := Low(Procs) to High(Procs) do
begin
T := TThread.CreateAnonymousThread(Procs[n]);
TThread.NameThreadForDebugging(AnsiString('Test thread N:' + IntToStr(n) + ' TID:'), T.ThreadID);
T.OnTerminate := AnonumousThreadTerminate;
T.FreeOnTerminate := true;
FThreadList.LockList;
try
FThreadList.Add(T);
finally
FThreadList.UnlockList;
end;
T.Start;
end;
end;
procedure TAnonumousThreadPool.AnonumousThreadTerminate(Sender: TObject);
begin
FThreadList.LockList;
try
FThreadList.Remove((Sender as TThread));
finally
FThreadList.UnlockList;
end;
end;
procedure TAnonumousThreadPool.TerminateRunningThreads;
var
L: TList;
T: TThread;
begin
if not Assigned(FThreadList) then
Exit;
L := FThreadList.LockList;
try
while L.Count > 0 do
begin
T := TThread(L[0]);
T.OnTerminate := nil;
L.Remove(L[0]);
T.FreeOnTerminate := False;
T.Terminate;
T.Free;
end;
finally
FThreadList.UnlockList;
end;
FThreadList.Free;
end;
destructor TAnonumousThreadPool.Destroy;
begin
TerminateRunningThreads;
inherited;
end;

Fin ici est de savoir comment vous pouvez l'appeler:

procedure TForm1.Button1Click(Sender: TObject);
begin
FAnonymousThreadPool.Start([ // array of procedures to execute
procedure{anonymous1}()
var
Http: THttpClient;
begin
Http := THttpClient.Create;
try
Http.CancelledCallback := function: Boolean
begin
Result := TThread.CurrentThread.CheckTerminated;
end;
Http.GetFile('http://mtgstudio.com/Screenshots/shot1.png', 'c:\1.jpg');
finally
Http.Free;
end;
end,
procedure{anonymous2}()
var
Http: THttpClient;
begin
Http := THttpClient.Create;
try
Http.CancelledCallback := function: Boolean
begin
Result := TThread.CurrentThread.CheckTerminated;
end;
Http.GetFile('http://mtgstudio.com/Screenshots/shot2.png', 'c:\2.jpg');
finally
Http.Free;
end;
end
]);
end;

Pas de fuites de mémoire, l'arrêt correct et facile à utiliser.

"anonyme threads" - Oh, génial.. qu'avez-Embarcadero imposé à nous maintenant?
Rien d'effrayant, vraiment. C'est un thread dont le comportement est fourni au moment de la création par une méthode anonyme. Il vous permet d'utiliser des fermetures lors de la définition des threads.
Il est continuellement créer/détruire des threads, quelque chose que je ai passé les 20 dernières années, de raconter, de développeurs afin d'éviter. Néanmoins, si ce n'est déjà commencé, je ne vois pas pourquoi il devrait y avoir un AV.
Gad, je suis sûr que ce n'est pas le adresse de la violation d'accès; $C0000005 Windows est le code d'exception pour des violations d'accès. S'il vous plaît copiez et collez le réel message d'erreur de texte. (Vous pouvez appuyer sur Ctrl+C dans la boîte de dialogue copier la totalité de la boîte de dialogue de texte.)
D'autres questions dans le nouveau code: Plutôt que de fuir, des fils qui se terminent par eux-mêmes pouvez obtenir la double-libéré. Depuis la méthode anonyme n'a pas de référence à l'objet thread, il ne peut pas vérifier la Terminated de la propriété, afin de l'appelant Terminate ne fait rien. (L'appel de Free appellerais Terminate de toute façon.) Il n'y a aucune raison pour qu'un thread-safe liste car il n'est jamais accessible dans un seul thread. Avez-vous songé à l'aide de Revue de Code? Il fournit plus de place pour parler de code de ces commentaires.

OriginalL'auteur Ivelin Nikolaev | 2012-05-01