Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
Hey,
wie der Titel schon versucht zu illustrieren: Ich habe ein Threadingproblem unter TurboDelphi. Abstrahiert gesehen will ich einfach nur einen Thread starten und sein Ende abwarten. Das Ganze soll dann einfach immer wieder und wieder geschehen. Sinn macht es zugegeben so wie es aussieht keinen, aber das ist nur die oberste Abstraktion auf der Fehlersuche.
Nun aber dieser Code eines Beispielprojects:
führt den Thread exakt 1x aus und befördert die while- zur Ehren-Endlosschleife.
Daher 2 Fragen:
1. Warum passiert das?
2. Gibt es einen besseren Weg auf das Ende des Threads zu warten?
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Suspend ist keine Ende des Thread. Es verhindert lediglich dessen Ausführung. Vergleichbar auch mit einem "Sleep(infinity)". Der Thread existiert aber weiterhin. Er wird nur beendet, wenn die Threadmethode (Execute) verlassen wird. Suspend solltest du nur benutzen, wenn du die Ausführung eines Threads verhindern möchtest aber ihn nicht komplett beenden willst. Wobei in der MSDN auch steht, dass es sich dabei um einen Suspendcounter handelt.
Einen Thread kann man nur ein mal starten. Also wenn er durchgelaufen ist, dann gilt er als beendet. Wenn du dann noch mal Resume aufrufst wird der Thread nicht noch einmal gestartet. Du bräuchtest dann eine neue Instanz von deinem Thread oder aber du musst deinen Thread so aufbauen, dass er wartet bis ihm eine neue Aufgabe mitgeteilt wurde. Also eine Endlosschleife innerhalb von Execute die auf Terminated wartet bzw evtl auch auf ein TEvent (wegen arbeit).
Um auf das Ende eines Threads zu warten würde ich eher OnTerminate benutzt. Also Anwendung sperren. Thread erstellen. Das Event OnTerminate zuweisen. Thread mit Resume starten und dann so lange warten bis das Event ausgelöst wird. Da du auch einen Sender bekommst könntest du so auch unterscheiden welcher sich da gerade meldet. Du müsstest dann wärend der Ausführung deinen Anwendung in einen Zustand versetzen in dem nichts passieren kann. Also evtl verschiedene Komponenten sperren etc. Der Vorteil wäre, dass deine Anwendung weiterhin vollständig intakt bleibt. Im OnTerminate darfst du den Thread aber nicht freigeben. Das führt zu einem 100%tigen Deadlock.
Alternativ kannst du auch mit TThread.WaitFor warten. Aber diese Methode wartet so lange bis er fertig ist. Wenn du pech hast reagiert deine Anwendung dann für Minuten gar nicht mehr. Du kannst auch die WindowsApi Funktion WaitForSingleObject benutzen. Der übergibt man TThread.Handle und eine Zeit die maximal gewartet werden soll. Dann könntest du alle 50 ms nachschauen ob sonst noch alles in Ordnung ist. Aber Normalerweise würde ich die eventbasierte Methode vorziehen. Das kommt dem Prinzip von Windows und der Threads am nächsten. Und du würdest nicht stumpf blockieren.
Registriert: Mo Sep 02, 2002 15:41 Beiträge: 867 Wohnort: nahe Stuttgart
Danke für die Antwort.
Richtig, der Thread läuft ja nur so durch. Irgendein kleines Detail vergesse ich beim Durchdenken irgendwie immer. Tatsächlich scheint die Suspend/Resume-Lösung doch noch zu funktionieren, wenn ich dafür sorge, dass der Thread immer wieder durchlaufen kann.
Wenn es aufgrund der Laufzeit nötig wird, werde ich auf die Terminate-Lösung umsteigen.
Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.