![]() |
Thread für einfache Funktionsauslagerungen
Hallo,
beim Umstellen eines Programms von Methoden auf Stored Procedures soll das ganze in einen Thread gepackt werden. Die SP sind komplex und zeitaufwendig, bisher wurden diese von der Mainform übernommen. Dabei gab es dann ein Infofenster mit einer Pseudoprogressbar die signalisiert das etwas in Arbeit ist. Bei der Umstellung auf SP friert nun dieses Infofenster ein. Lösung: Auslagerung in Thread. Ist der nachfolgende Ansatz so richtig oder was ist noch zu beachten. Geht er vielleicht einfacher? Danke schon mal....
Delphi-Quellcode:
TMachWasLangesInDerDBThread = class(TThread)
private fSPQuery : TIBQuery; fInProgress : Boolean; protected procedure Execute(); override; public constructor create(const aPKey,aTKey:TKey; aChildLevel:Integer); destructor Destroy; override; property InProgress : Boolean read fInProgress; end; constructor TMachWasLangesInDerDBThread.create(const aPKey,aTKey:TKey; aChildLevel:Integer); begin inherited create(False); FreeOnTerminate := False; fInProgress := True; fSPQuery := TIBQuery.Create(nil); try fSPQuery.SQL.Text:='EXECUTE PROCEDURE P_SORT...'; fSPQuery.ParamByName(...); except on e: exception do begin showmessage(e.Message); end; end; end; destructor TMachWasLangesInDerDBThread.Destroy; begin if Assigned(fSPQuery) then begin fSPQuery.Free; end; inherited destroy; end; procedure TMachWasLangesInDerDBThread.Execute; begin try fSPQuery.ExecSQL; except on e: exception do begin showmessage(e.Message); end; end; fInProgress := False; end; .... im Hauptprozess Aufruf durch... ... MeinInfoFenster.show; aMYThread := TMachWasLangesInDerDBThread.create(...); try while aMYThread.InProgress do begin MeinInfoFenster.Action; Sleep(1000); end; finally aMYThread.Free; end; ... |
AW: Thread für einfache Funktionsauslagerungen
Ist die verwendete DB-Komponente Thread-Save?
D.h. darfst du von unterschiedlichen Query-Komponenten auf eine einzige Connection-KOmponente zugreifen? Falls nicht musst du in jedem Thread eine eigene DB-Verbindung aufbauen. |
AW: Thread für einfache Funktionsauslagerungen
das wäre nicht das Problem, ich kann ja die Entsprechenden Infos aus dem Hauptthread übergeben.
Was mir mehr sorgen macht, ist...
Delphi-Quellcode:
was ist wenn das durch ein Fehler zu einer Endlosschleife wird? Wie kann ich das vielleicht anders lösen?
while aMYThread.InProgress do
begin MeinInfoFenster.Action; Sleep(1000); end; |
AW: Thread für einfache Funktionsauslagerungen
Wie wäre es ohne sleep aber mit Triggerung durch einen Timer?
oder so:
Delphi-Quellcode:
Gruß
while aMYThread.InProgress do
begin aMyThread.InProgres:=false; {ich hab das read gesehen.....} MeinInfoFenster.Action; Sleep(1000); end; K-H |
AW: Thread für einfache Funktionsauslagerungen
Warum kann Sleep nicht endlich aus der RTL rausgeworfen werden? :(
Deutlich besser ist WaitForSingleObject, dann lässt sich die "Wartepause" auch abbrechen (sonst z.B. nervig wenn bei Programmende einige Threads noch die eine oder andere Sekunde schlafen, beim System runterfahren, wenn man einfach nur abbrechen will...). Zum Beispiel mit einem Event (auf den man damit wartet). |
AW: Thread für einfache Funktionsauslagerungen
Lass das mit Sleep und so weg, und mach eine Synchronize-Funktion am Ende das Thread, wo du
Delphi-Quellcode:
hast. Damit sind beide Threads (Haupthread, also dein Fenster, und dein "Arbeiterthread") unabhängig von einander. Das mit
fInProgress := False;
Delphi-Quellcode:
im except würd ih ändern. Dass könnte unter umständen mal knallen. Verwende lieber MessageBox von Windows. Ist sicherer und bietet mehr :-D
ShowMessage
Nachtrag, wegen anderen Posts : Oder mit WaitForSingleObject, wie schon erwähnt :-D. Ich persönlich find es blöd, da die Hauptanwendung im Endeffekt wieder einfriert. Gruß NickelM |
AW: Thread für einfache Funktionsauslagerungen
Wird das Query wirklich im Thread ausgeführt. Denn wenn die Komponente in TThread.create erstellt wird, gehört sie zumindest noch dem Mainthread (müsste man überprüfen, wie die Komponente arbeitet.
Ansonsten: sleep vermeiden, steht ja schon da. Edit: Zitat:
|
AW: Thread für einfache Funktionsauslagerungen
Hi ibp,
also so wie ich das sehe, würde ich im Thread auf jedenfall eine eigene Connection aufbauen. Außerdem sei beachtet, dass der Constructor des Threads im Kontext des aufrufenden Threads - also nach Deinem Beispiel wahrscheinlich des Hauptthreads - ausgeführt wird. Ich würde daher alle Speichersachen erst am Anfang von Execute erzeugen/anlegen und auch am ende von Execute freigeben. [EDIT]Wurde ja schon so von sirius geschrieben :-([/EDIT] Dann der Aufruf. Es gibt da eben zwei Möglichkeiten - die eine ist nach meiner Ansicht der lineare Ansatz mit warten auf Beendigung wie du es gemacht hast. Sleep ist dafür nach meiner Meinung schlecht ich würde eher aktives Warten machen -> mit z.B. ![]() Der andere ist der Ereignisgesteuerte. D.h. zerteilen von start und ende. Es gibt eine Methode die den Start steuert und nach dem Start der Threads die Oberfläche in einen "Bitte warten Zustand" bringt und damit endet. Dem Thread wird noch eine Methode übergeben für Beenden - vielleicht mit einer Aussage wie erfolgreich das war was er tun soll. In dieser Methode wird dann die Bedienung der Oberfläche wieder frei gegeben z.B. Statusbar wird wieder geschlossen - und alles andere was noch so gemacht werden muss, nachdem die Aufgabe des Threads erledigt ist. Gruß, Chris [EDIT] Endlosschleife würde ich über das OnTerminate-Event des Threads verhindern mit einer lokalen Variable in der Anwendung. Diese Variable wird bei OnTerminate gesetzt und neben InProgress mit abgefragt
Delphi-Quellcode:
[/EDIT]
while MyThread.InProgress and l_IsRunning do
|
AW: Thread für einfache Funktionsauslagerungen
also das Sleep war nur für das Infofenster, weil das so gerannt ist, das würde entsprechend noch angepasst werden und damit fliegt das Sleep wieder raus.
Delphi-Quellcode:
aktualisiert eigentlich nur nach einer bestimmten Anzahl von Aufrufen das Info-Fenster.
MeinInfoFenster.Action;
Showmessage steht da nur zu Testzwecken! Brauche ich den ein Synchronize wenn Thread.Exceute abgearbeitet wurde? |
AW: Thread für einfache Funktionsauslagerungen
Zitat:
Gruß, Chris |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:22 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