Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Thread, Beendigung, IDE (https://www.delphipraxis.net/186401-thread-beendigung-ide.html)

haentschman 1. Sep 2015 06:25

Thread, Beendigung, IDE
 
Hallo Alle...:P

Ich hätte gern mal ein Problem...8-)

Ich arbeite gern und viel mit WorkerThreads. Dafür benutze ich keine Bibliothek wie Omni sondern ein einfaches Konstrukt für TThread in Kombination mit einer Liste dafür. Die Threads melden ihre Fertigstellung über eine Message bei der Liste an und die Liste trägt ihn aus.

Soweit so gut funktioniert das stabil und zuverlässig. Bei dem aktuellen Projekt dauert es aber nach dem CloseQuery der Form beim Beenden ca.5 Sekunden bis der Prozess, ohne Fehler und Speicherlecks, wieder in die IDE zurückkehrt. :gruebel:
Der Debugger sagt vor dem Schließen:
1 Thread erzeugt
1 Thread in Liste
1 Thread Terminated
1 Thread freigegeben
...also Alles wie es sein soll. :roll:

Starte ich die Worker Threads nicht, kommt die IDE sofort zurück. Es hat also was damit zu tun. Wie kann ich herausfinden was das "Beenden" blockiert? Der Thread läuft definitiv nicht mehr.

Danke...:P

Dejan Vu 1. Sep 2015 06:41

AW: Thread, Beendigung, IDE
 
Meine Glaskugel sagt, das Du im 'WaitForSingleObject' 5 Sekunden wartest.

Aber ehrlich gesagt: Wie soll man das ohne Code wissen? Zeig mal den Code deines Threads.

haentschman 1. Sep 2015 07:47

AW: Thread, Beendigung, IDE
 
Liste der Anhänge anzeigen (Anzahl: 1)
Bitteschön die Unit...8-)

Beim Beenden und dem Clear der Liste im Destruktor ist der Count 0. Wenn ich die Threads programmtechnisch via StopAllWorker "abbreche" kommt das Program sofort in die IDE zurück. Wenn ich den Thread fertig laufen lasse wird der Thread genauso ausgetragen(gleiche Debugger Steps). Aber dann braucht´s ca. 5 Sekunden bis in die IDE. :gruebel:
In der Threadverwaltung sind dann plötzlich 2 Threads gelistet die nach dem FormCloseQuery erst eröffnet werden. Keine Ahnung wo die hingehören. :roll:

Zugegeben, ich bin ratlos. Ich glaube nicht, das das mit meinen Workern zusammenhängt. Ich glaube eher an die visuellen Componenten welche im Hintergrund noch aufräumen. Der Status der Progressbar und des StepControls ist bei den verscheidenen "Abbruchvarianten" unterschiedlich.

Der schöne Günther 1. Sep 2015 08:03

AW: Thread, Beendigung, IDE
 
Möchtest du vielleicht auch noch einen Dreizeiler dazulegen wie man das benutzen soll?

Und warum das "of object"? Ich hasse das, warum soll ich keine anonymen Methoden übergeben können? Mach doch bitte "reference to procedure(..)".

haentschman 1. Sep 2015 08:12

AW: Thread, Beendigung, IDE
 
Handling:

1. eigenen Worker bauen mit = class(TWorker)
2. Worker Liste instanzieren
3. Worker instanzieren
4. Worker in die Liste legen.
5. der Rest geht fast von selbst...:zwinker:
6. Das Wegwerfen der Liste hat ein koordiniertes Aufräumen der Threads zur Folge. (selbstverständlich sollte im Thread, je nach Komplexität, mehrfach auf Terminated geprüft werden. Sonst läuft der Thread logischerweise bis zum Ende durch :zwinker:)

PS. Ich bin grad am Ausbauen der Visuellen Rückmeldungen. Mal schauen.

Zitat:

Und warum das "of object"? Ich hasse das, warum soll ich keine anonymen Methoden übergeben können? Mach doch bitte "reference to procedure(..)".
..erklär mal genauer warum du das nicht magst. Oder anders: Was ist daran falsch?

Mavarik 1. Sep 2015 08:36

AW: Thread, Beendigung, IDE
 
Ok vielleicht verstehe ich es nicht...

Aber der Teil, der die Arbeit auf die Worker verteilt fehlt...
Was Du angefügt hast ist doch nicht anderes wie ein Threadrumpf und eine Liste die Threads verwaltet.

Wo ist der Sync, der Wait, der Terminate usw.

haentschman 1. Sep 2015 10:02

AW: Thread, Beendigung, IDE
 
Hallo...
Zitat:

Wo ist der Sync, der Wait, der Terminate usw.
...alles im Threadrumpf bzw der Liste.
Delphi-Quellcode:
const
  PM_Finish_Thread = WM_USER + 1;

procedure TdWorkerList<T>.Remove(aThread: TThread);
begin
  aThread.Terminate;
  aThread.WaitFor;
  aThread.Free;
  inherited Remove(aThread);
end;

procedure TdWorkerList<T>.TreadFinished(var Msg: TMessage);
begin
   if (not FDestroying) and (Msg.Msg = PM_Finish_Thread) then
   begin
     Remove(TThread(Msg.wParam));
   end;
end;
Der Thread selbst schickt eine Message an die Liste das er fertig ist.
Delphi-Quellcode:
procedure TWorker.DoOnTerminate(Sender: TObject);
begin
  PostMessage(FListHandle, PM_Finish_Thread, wParam(Self), 0);
end;
Letztendlich ist das alles unerheblich. Der Thread ist definitiv fertig und freigegeben. Das schließt dieses Konstukt aus. Ich hatte gehofft das ihr andere Ideen habt.

Mavarik 1. Sep 2015 10:58

AW: Thread, Beendigung, IDE
 
Also sollen das keine WorkerThread für eine Aufgabe sein, sondern Du Assignest Du nur in eine Liste um alle Terminieren zu können?

Sir Rufo 1. Sep 2015 11:15

AW: Thread, Beendigung, IDE
 
Nur so am Rande bemerkt, wer diesen Block
Delphi-Quellcode:
TThread.Terminate;
TThread.WaitFor;
TThread.Free;
so aufruft, der hat sich
Delphi-Quellcode:
TThread.Destroy
noch nicht angesehen, denn dann würde man dieses Triumvirat ersetzen durch
Delphi-Quellcode:
TThread.Free;
;)

haentschman 1. Sep 2015 11:20

AW: Thread, Beendigung, IDE
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Maverik,

wie du schon sagtest. Das ist der Rumpf mit den Events und der "Habe fertig" Logik. Auf TWorker setzen dann die eigentlichen Worker auf. Die Liste dient nur der Verwaltung der Threads (jeder Thread trägt sich quasi selbst aus der Liste aus).
Ich hatte das eigentlich nur mit angeführt um die Zusammenhänge besser zu erklären. Das Konstrukt funktioniert in einem anderen Projet ganz normal. Auch die IDE ist nach der Beendigung des anderen Projektes sofort wieder da. Nur in diesem ist die Verzögerung beim Beenden vorhanden.
Meine erstellten Threads tragen Namen. Die nach dem Beenden erzeugten Threads, und das Warten auf deren Beendigung, haben nur Nummern. Mit welchem Werkzeug kann ich herausfinden wer die Threads erstellt?

PS: Auch mit normal TThread und FreeOnTerminate ist beim Beenden die Verzögerung.

Zitat:

so aufruft, der hat sich TThread.Destroy noch nicht angesehen, denn dann würde man dieses Triumvirat ersetzen durch TThread.Free;
hast du es mal nicht nur mit TThread probiert sondern mit Ableitungen und erstellten Interfaces im Constructor der Ableitung? Vom reinen Quelltext (TThread.Destroy) gebe ich dir Recht. Nur hagelt es in diesem Falle Fehlermeldungen bevor der Destructor von TThread aufgerufen wird. (und damit das Terminate + WaitFor). Meine Fehler haben mit der Datenbankverbindung zu tun. Mein DB Framework, welches als Interface im Constructor des Workers erstellt wird, ist bereits über die Referenzzählung abgräumt, da die Destructoren durchlaufen werden.
In diesem Falle ist das Terminate und WaitFor vor dem Free notwendig und richtig. :zwinker: Oder hast du dafür auch eine Patentlösung... 8-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:41 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz