Nochmal ich zum Thema Thread, diesmal jedoch anders gelagert.
Ein Thread wird erzeugt und direkt gestartet, läuft jedoch durchaus etwas länger. Bei einem erneuten Aufruf der Funktion, die den Thread zuvor gestartet hat, wird dann also erst geprüft, ob der alte Thread vielleicht noch läuft. Abfrage einer Integer über eine class function. Läuft er, wird er terminiert anschl. WaitFor und alles wieder freigegeben (FreeAndNil() - erst dann neu gestartet.
Da er wie gesagt länger läuft wird er u.U. vom ProgrammEnde "überrascht" oder aber soll neu gestartet werden (neue Anforderung). Dann aber sollte es kein OnTerminate mehr geben, weil eine Aktualisierung der GUI des Hauptthreads nicht nötig ist. Deshalb möchte ich erreichen, dass ein OnTerminate auch tatsächlich nur dann ausgelöst wird, wenn der Thread "normal" - also nach Ablauf von Execute ohne Unterbrechung - beendet wurde! Gem. Standard-Verhalten von TThread würde OnTerminate-Event jedoch auch dann aufgerufen, wenn der Thread über .Free "beendet" würde. TThread.Free() bzw. .Destroy() termniniert und wartet auf Ende, ist also grundsätzlich ok, ruft aber OnTerminate auf - auch wenns wie in meinem Fall nicht sein soll.
Ich hab mir jetzt durch das überschreiben von DoTerminate geholfen.
ThreadUnit
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30:
| TGPSGesamtThread = class(TThread) private FGesamt: Integer; FHTTP: TIdHTTP; FxmlDoc: TJvSimpleXML; FURL: String; protected procedure Execute; override; public constructor Create( url: String; callback: TNotifyEvent ); class function IsRunning: boolean; procedure DoTerminate; override; property Gesamt: Integer read FGesamt; end;
constructor TGPSGesamtThread.Create( url: string; callback: TNotifyEvent ); begin FURL := RemoveLimit(url); OnTerminate := callback; inherited Create( false ); end;
procedure TGPSGesamtThread.DoTerminate; begin if not Terminated then inherited DoTerminate; end; |
HauptUnit
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| . if TGPSGesamtThread.IsRunning then StopThread(); FThrGesamt := TGPSGesamtThread.Create( FInternalURL, AfterFinishedGesamtThread ); .
procedure TGPSAPI.StopThread(); begin if Assigned( FThrGesamt ) then begin with FThrGesamt do begin Terminate; WaitFor; end; FreeAndNil( FThrGesamt ); end; end; |
War das verständlich oder totaler Bockmist?!
Das funktioniert soweit auch recht gut und eigentlich so, wie ich es gerne hätte
Frage ist nur, ist das i.O. so ... oder doch eher von hinten durch die Brust ins Auge?!
Dank & Gruss
nru