Einzelnen Beitrag anzeigen

Benutzerbild von haentschman
haentschman

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

mehrere Threads sauber beenden

  Alt 10. Jan 2011, 08:07
Delphi-Version: XE
Guten Morgen alle...

am Wochenende hab ich mich mal mit Threads intensiv beschäftigt. Zuerst hab ich die OmniThreadLibary ausprobiert. So viele MemoryLeaks (aus der Libary) hab ich in meinem Leben noch nicht gesehen. Danach hab ich TThread versucht.
Nach gefühlten hunderten Forenbeiträgen, Hilfeseiten und ausprobieren dessen habe ich das Gefühl die Katze beißt sich in den Schwanz...
Gegeben:
- Mainunit
- UnitA
- enthällt KlasseA
- UnitB
- enthällt KlasseB(TThread) mit IdHTTP
Funktion:
- Mainunit instanziert Objekt von KlasseA
- KlasseA erzeugt TObjectlist für die Threads
- KlasseA erzeugt Objekte von KlasseB (je nach Anfrage 1-4)
- beim Erzeugen des Threads wird der Thread in die Objectlist gelegt
- im OnTerminate des Threads das Objekt aus der Liste entfernt
- Threads sollen parallel laufen also nicht warten bis einer fertig ist

Solange das Programm beendet wird wenn kein Thread am laufen ist, ist alles in Ordnung. Wird die Anwendung bei laufenden Threads beendet bleiben die Threads stehen Macht man weiter gibt es MemoryLeaks in den Indys weil die Threads einfach abgewürgt werden. Ok, dachte ich, manuell entfernen...

Variante 1:
- FreeOnTerminate:= True // Threads sollen sich selbst freigeben wenn beendet
Delphi-Quellcode:
destructor KlasseA.Destroy;
begin
  while not (FThreadList.Count = 0) do
    begin
      if Assigned((FThreadList.Items[0] as KlasseB)) then
        (FThreadList.Items[0] as KlasseB).WaitFor;
    end;
end;
* gibt Zugriffsverletungen... Inzwischen weiß ich, daß WaitFor in Verbindung mit FreeOnTerminate nicht zu gebrauchen ist, da das Handle irgendwo weggeworfen wird und dieser "Bug" schon ein paar Jahre existiert.

Variante 2:
- FreeOnTerminate:= False;
Delphi-Quellcode:
destructor KlasseA.Destroy;
begin
  while not (FThreadList.Count = 0) do
  begin
    if Assigned((FThreadList.Items[0] as KlasseB)) then
    begin
     (FThreadList.Items[0] as KlasseB).WaitFor;
     (FThreadList.Items[0] as KlasseB).Free;
    end;
  end;
end;
* soweit so gut. Die aktuellen Threads laufen fertig und sind freigegeben. Nur hab ich dann Im laufenden Betrieb noch haufenweise Objekte im Speicher, welche nicht mehr in der ObjectList stehen, da die Threads sich im OnTerminate austragen.

Wo gebe ich quasi im laufenden Betrieb die Objekte frei ? (nach OnTerminate). Die Beiträge in den Foren laufen alle im Prinzip auf folgendes hinaus:
Delphi-Quellcode:
Thread.Create;
///
Thread.WaitFor;
ThreadFree;
* das funktioniert auch, nur laufen die Threads nicht parallel sondern nacheinander. (logisch)

Bitte bringt etwas Licht ins Dunkel... Danke
  Mit Zitat antworten Zitat