Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Prozessbar wärend Prozess laufen lassen
Jakane - Mi 11.07.12 10:30
Titel: Prozessbar wärend Prozess laufen lassen
Hallo liebe Delphi-Helfer :)
Mit eine Script lade ich mir Daten in meine Datenbank. Sind es nur wenige Datensätze, dann stört es keinen, aber bei 30.000 und mehr, kann das schon 2-3 Minuten dauern :-/
Allerdings springt der Timer, der die Prozessbar laufen lässt, gar nicht an, weil das Script die Prozedur blockiert :(
Delphi-Quelltext
1: 2: 3:
| Timer.Enabled:= True; IBScript.ExecuteScript; Timer.Enabled:= False; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TfmHaupt.TimerTimer(Sender: TObject); begin Prozessbar_einstellen(PB, 200, Zeit, 0); Inc(Zeit); if Zeit > 200 then Zeit:= 0; end; |
Wie kann ich meine Prozessbar sehen, wie sie läuft, wärend das Script läd?
Danke für die Hilfe :)
Moderiert von
Narses: Code- durch Delphi-Tags ersetztModeriert von
Narses: Topic aus Dateizugriff verschoben am Mi 11.07.2012 um 11:28
bummi - Mi 11.07.12 10:37
Den Script in einem Thread ausführen? Ich kenne mich mit leider IB nicht aus ...
Jakane - Mi 11.07.12 10:39
bummi hat folgendes geschrieben : |
Ich kenne mich mit leider IB nicht aus ... |
kannst auch jeden anderen, nicht beeinflussbaren Prozess nehmen, zB das versenden einer eMail
bummi hat folgendes geschrieben : |
Den Script in einem Thread ausführen? |
was ist ein Thread?
Delete - Mi 11.07.12 10:54
Code der quasi parallel ausgeführt wird. Einfach mal Google bemühen. Es finden sich dazu recht viele Tutorials.
HelgeLange - Mi 11.07.12 15:35
Trotzdem weiss man nicht, wielange es dauern wird. Dadurch wird es schwer, eine progressbar dorthinzusetzen. Was du natürlich machen kannst : das script schiesst firebird events und du weisst, wo es gerade ist. Natürlich nicht zu oft :)
Die Events empfängst Du in deinem mainthread und nutzt die info um die progressbar abzuarbeiten
Jakane - Fr 13.07.12 10:00
Hab mir inzwischen einiges durchgelesen, aber irgendwas geht immernoch nicht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TProzessbalken = class(TThread) private FProgressBar: TProgressBar; protected procedure Execute; override; public constructor Create(ProgressBar: TProgressBar); end; |
Delphi-Quelltext
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:
| constructor TProzessbalken.Create(ProgressBar: TProgressBar); begin FProgressBar:= ProgressBar; FreeOnTerminate := True; inherited Create(False); end;
procedure TProzessbalken.Execute; var i: Integer; begin try for i := 1 to 100 do begin FuP_S._Prozessbar_einstellen(FProgressBar, 100, i, clRed); Sleep(100); end; except on e: exception do begin ShowMessage('Fehler im Parallel-Prozess.'); end; end; end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| var Prozessbalken: TProzessbalken; begin Prozessbalken:= TProzessbalken.Create(PB); Prozessbalken.Resume; IBSFTT.ExecuteScript; Prozessbalken.Suspend; |
Bisher macht er nicht mehr als vorher auch...
Er läd das Script, aber der Balken bewegt sich nicht.
Weiss jemand was falsch ist? :(
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
Narses - Fr 13.07.12 10:19
Moin!
Jakane hat folgendes geschrieben : |
Weiss jemand was falsch ist? |
Fast alles... :? Du hast es genau verkehrt herum gemacht: die eigentliche (unsichtbare) Arbeit muss in den Thread, die GUI bearbeitest du im Haupt-Thread. Da kannst du die Progressbar z.B. mit einem einfachen TTimer weiterlaufen lassen. :idea:
Randproblem: Man darf aus Threads heraus nicht (unsynchronisiert) auf die VCL zugreifen, das knallt immer (früher oder später)! :mahn:
cu
Narses
Jakane - Fr 13.07.12 10:56
Jetzt versteh ich gar nichts mehr :(
Kann jemand mein Code umbauen, das es funktioniert?
Narses - Fr 13.07.12 11:24
Moin!
Jakane hat folgendes geschrieben : |
Mit eine Script lade ich mir Daten in meine Datenbank. Sind es nur wenige Datensätze, dann stört es keinen, aber bei 30.000 und mehr, kann das schon 2-3 Minuten dauern |
Das muss in den Thread, nicht das Weiterschieben der ProgressBar. :idea:
cu
Narses
Jakane - Fr 13.07.12 11:33
Moderiert von
Narses: Komplett-Zitat des letzten Beitrags entfernt.
Hilft grad nur bedingt weiter.
Wenn ich das Script.Execute in den Thread schieben, wie sag ich dann der Prozessbar wie lange die laufen muss? ohne das sie mit den nachfolgenden Ereignissen weiter macht?
bummi - Fr 13.07.12 11:51
Wie lange es dauert wird schwierig sein abzuschätzen, ich weiß nicht ob es bei Firebird Events o.ä. gibt, notfalls könnte man eine "Tabelle" mit Statusschritten füllen und die pollen, die Fertigstellung kannst Du über OnTerminate des Threads abfackeln
Narses - Fr 13.07.12 11:51
Moin!
Jakane hat folgendes geschrieben : |
Wenn ich das Script.Execute in den Thread schieben, wie sag ich dann der Prozessbar wie lange die laufen muss? |
Du weißt doch eh nicht, wie lange der Thread läuft, oder? :zwinker: Ansatz: Schätze die Laufzeit am Anfang ab, lass die ProgresBar laufen, wenn die ProgressBar das Ende erreicht hat, aber der Thread noch läuft, wieder am Anfang anfangen... Pech gehabt. :nixweiss: Genauer geht´s nicht. :?
Jakane hat folgendes geschrieben : |
ohne das sie mit den nachfolgenden Ereignissen weiter macht? |
Klar, alle weiteren Aktionen müssen in ein OnTerminate-Ereignis des Threads rein, solange der läuft, tut das Hauptprogramm nix (ausser die ProgressBar zu bewegen (per Timer) und auf sonstige Userinteraktionen (z.B. Fenster verschieben) zu reagieren). :idea:
cu
Narses
//EDIT: Nach der Idee von
bummi :beer: geht´s natürlich schon genauer, aber eine Schätzung wird das immer bleiben. :nixweiss: Die Frage ist halt, wie genau die wird. ;)
Jakane - Di 17.07.12 09:06
Danke Narses und auch alle anderen.
Hat zwar ewig gedauert eh ichs begriffen hab, aber jetzt gehts.
Und mit einer Programmweiten Varriablen brauch ich nur noch das Script in dem Thread haben :)
Jakane - Mo 23.07.12 10:12
Irgendwas scheint immernoch falsch zu sein :(
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| begin Database.Close; Database.Open; if not OpenDialog.Execute then EXIT;
IBScript.Script.LoadFromFile(OpenDialog.FileName); _Parallel_Prozessbar(IBScript); end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| type TProzessScript = class(TThread) private PIBScript: TIBScript; protected procedure Execute; override; public constructor Create(IBScript: TIBScript); end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| procedure _Parallel_Prozessbar(IBScript: TIBScript); var ProzessScript: TProzessScript; begin ProzessScript:= TProzessScript.Create(IBScript); ProzessScript.Resume; end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| procedure TProzessScript.Execute; begin ProzessFertig:= False; PIBScript.ExecuteScript; ProzessFertig:= True; end; |
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| constructor TProzessScript.Create(IBScript: TIBScript); begin PIBScript:= IBScript; FreeOnTerminate := True; inherited Create(False); end; |
Der 1. Lauf klappt immer problemlos, aber wenn ich das das 2. mal aufrufe bekomm ich Fehlermeldungen.
Den Transactionsfehler bekomme ich auch wenn ich vorher mit PIBScript.Transaction auf Activ setze.
Weiss einer Rat?
Moderiert von
Narses: Code- durch Delphi-Tags ersetzt
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!