So, nachdem ich das Programm in dem es hier eigentlich ging, ohne Uhrzeit/Statusbalken fertig gemacht habe, versuche ich das Prinzip mit den Threads jetzt auf ein neues Programm, was ich jetzt machen soll.
Das Programm is an sich ma wieder nix wildes, durchforstet die Datenbank nach gewissen Daten, filtert/sortiert/etc und gibt diese dann aus.
...
Jetzt habe ich einen Thread geschrieben, der dann im Hauptfenster einen Laufbalken immer via "StepIt()" aktualisieren soll.
Das Ganze hat keinen Zusammenhang zu den eigentlichen Daten, sondern dient nur der Unterhaltung des Benutzers, d.h. der ist zu ende, fänge vorne wieder an, usw.
Hier der Quelltext des Threads
Delphi-Quellcode:
{*--- TProgressSimulator ---*}
procedure TProgressSimulator.Execute();
begin
// do as long as thread isn´t terminated
while self.Terminated = False do
begin
// Kommentar fürs Forum: Variante 1
Synchronize(frmMain.simulateProgress);
Application.ProcessMessages();
// Kommentar fürs Forum: Variante 2
frmMain.barProgress.StepIt();
Application.ProcessMessages();
Sleep(100);
end;
end;
Beide Varianten funktionieren übrigens nicht!
(Das die 2. nicht Threadsicher ist, weiß ich, aber damit wollte ich nur testen, ob das was mit Synchronize zu tun hat).
Dieser Thread hat also via Synchronize eine Methode von TfrmMain aufgerufen, welche so aussieht:
Delphi-Quellcode:
// simulates progress
procedure TfrmMain.simulateProgress();
begin
try
barProgress.StepIt();
updateGui();
except
on e:
Exception do begin ;
end;
end;
end;
Ich habe aber wieder das Gleiche Problem wie zuvor: Das geht nur so lange gut, wie mein Programm nix macht.
Sobald die eigentliche Verarbeitung in "TfrmMain" anfängt und das Programm die Datenbank durchsucht etc. "hängt" der Thread.
Das äussert sich dann so, dass der Code in "Execute" immer nur dann ausgeführt wird, wenn das Programm an sonsten grade nix zu tun hat.
Ist das Programm beschäftigt, macht der Thread einfach gar nix mehr ... exakt solange bis das Programm fertig mit der Verarbeitung ist.
Ein "Application.ProcessMessages" innerhalb der Verarbeitung löst das Problem zwar - DANN macht der Thread auch was er soll, nämlich genau 1x je "Application.ProcessMessages" - aber das ist ja etwas witzlos, denn der Balken soll ja konstant laufen und nich nur, wenn im eigentlichen Quelltext ma ein "ProcessMessage" vorkommt.
Hat wer ne Ahnung, woran das liegt, bzw. wie ich das lösen kann?
...
Ok, ich könnte jetzt die Verarbeitung an sich noch in einen extra Thread auslagern, aber das gefällt mir nich wirklich, da dass die Verarbeitung, bzw. Kommunikation mit dem Benutzer/der
GUI unnötig verkomplizieren würde.
...
Hier noch ma die Methode, die die eigentliche Verarbeitung und den Thread steuert
Delphi-Quellcode:
procedure TfrmMain.btnStartClick(Sender: TObject);
var
logMsg:
String;
begin
// check params for errors
// <unnötig hier>
// disable gui & start threads
enableGui(false);
progSimulator.Resume();
// do processing
try
startProcessing();
writeStatus('
Verarbeitung abgeschlossen', ML_BOTH);
ShowMessage('
Verarbeitung abgeschlossen');
except
on e:
Exception do
begin
logMsg := '
Unerwarteter Fehler aufgetreten: ' + e.
Message;
writeStatus(logMsg, ML_LOG_ONLY);
ShowMessage(logMsg);
end;
end;
// stop threads & re-enable gui
progSimulator.Suspend();
enableGui(true);
end;
Danke im Voraus
cu Patrick