AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

mehrere Threads sauber beenden

Ein Thema von haentschman · begonnen am 10. Jan 2011 · letzter Beitrag vom 9. Dez 2013
 
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.431 Beiträge
 
Delphi 12 Athens
 
#17

AW: mehrere Threads sauber beenden

  Alt 11. Jan 2011, 23:20
Kurze Rückmeldung...

mit Unterstützung von DeddyH sind wir auf folgendes Lösungsprinzip gekommen.

1. eine Liste für die Threads (hier als generische Liste unter XE)
Delphi-Quellcode:
TMyCustomThreadList = TList<TLoader>; // TLoader = class TThread

  TMyThreadList = class(TCustomThreadList)
  strict private
    FListHandle: HWND;
    FDestroying: Boolean;
    procedure TreadFinished(var Msg: TMessage); message PM_Finish_Thread; // Methode die die Message empfängt
  public
    constructor Create;
    destructor Destroy; override;
    procedure Clear;
    procedure Add(aThread: TLoader);
    procedure Remove(aThread: TLoader);
  end;
Delphi-Quellcode:
constructor TMyThreadList.Create;
begin
  inherited;
  // Fensterhandle erzeugen damit auch Messages enmpfangen werden können
  FListHandle := AllocateHWnd(TreadFinished);
end;
Delphi-Quellcode:
destructor TMyThreadList.Destroy;
begin
  Clear;
  DeAllocateHwnd(FListHandle);
  inherited;
end;
Delphi-Quellcode:
procedure TMyThreadList.Remove(aThread: TLoader);
begin
  aThread.Terminate;
  aThread.WaitFor;
  aThread.Free;
  inherited Remove(aThread);
end;
Delphi-Quellcode:
procedure TMyThreadList.Clear;
begin
  FDestroying:= True;
  while Count > 0 do
    Remove(Items[0]);
end;
Delphi-Quellcode:
procedure TMyThreadList.Add(aThread: TLoader);
begin
  inherited Add(aThread);
  aThread.ListHandle := FListHandle;
end;
2. Thread erzeugen und starten
Delphi-Quellcode:
  Loader:= TLoader.Create;
  // Zuweisung der Methode die nach der Arbeit des Threads ausgeführt wird (Methoden anpassen)
  Loader.OnFinish:= FinishLoad;
  FThreads.Add(Loader); // FThreads private Property von TMyThreadList
  Loader.Start; // Start gibts erst ab 2010 ? Ansonsten Resume;
3. Thread versendet User Message wenn fertig
Delphi-Quellcode:
const
  PM_Finish_Thread = WM_USER + 1;
.
.
// Methode die der TThread Methode OnTerminate zugewiesen ist
procedure TLoader.OnThreadTerminated(Sender: TObject);
begin
  PostMessage(FListHandle, PM_Finish_Thread, wParam(Self), 0);
end;
4. Message kommt an
Delphi-Quellcode:
procedure TXWebThreadList.TreadFinished(var Msg: TMessage);
begin
//FDestroying wird im destructor gesetzt, damit nicht 2 Mal entfernt wird. Wenn die Liste beim Beenden der
//Anwendung die Liste leer macht würde die Message ja auch ankommen.
  if (not FDestroying) and (Msg.Msg = PM_Finish_Thread) then
    Remove(TXWebLoader(Msg.wParam)); // Thread aus Liste entfernen und freigeben
end;
Fazit:
Der Unterschied besteht eigentlich nur darin, daß:
1. Der Thread über eine Message mitteilt daß er fertig ist. Nicht Ereignis. Ereignise werden sequentiell abgearbeitet und der Thread konnte sich nicht beenden solange die Ereignisse nicht abgearbeitet sind. Da war die Freigabe das Problem. Da kam die "Endlosschleife" her.
2. die Liste selbst die Threads entfernt und freigibt
3. dadurch daß jetzt WaitFor ordentlich funktioniert weil die Threads weiterlaufen (wegen Message) werden die Threads sauber beendet und freigegeben.

Hoffe, daß das Ganze anderen viel Nerven erspart...
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz