Autor Beitrag
Jakane
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: Mi 11.07.12 10:30 
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 :(

ausblenden Delphi-Quelltext
1:
2:
3:
  Timer.Enabled:= True;
  IBScript.ExecuteScript;
  Timer.Enabled:= False;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TfmHaupt.TimerTimer(Sender: TObject);
begin  // Interval = 10
  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 user profile iconNarses: Code- durch Delphi-Tags ersetzt
Moderiert von user profile iconNarses: Topic aus Dateizugriff verschoben am Mi 11.07.2012 um 11:28
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mi 11.07.12 10:37 
Den Script in einem Thread ausführen? Ich kenne mich mit leider IB nicht aus ...

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Jakane Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: Mi 11.07.12 10:39 
user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Ich kenne mich mit leider IB nicht aus ...

kannst auch jeden anderen, nicht beeinflussbaren Prozess nehmen, zB das versenden einer eMail

user profile iconbummi hat folgendes geschrieben Zum zitierten Posting springen:
Den Script in einem Thread ausführen?

was ist ein Thread?
bummi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: Mi 11.07.12 10:52 

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: 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

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Jakane Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: Fr 13.07.12 10:00 
Hab mir inzwischen einiges durchgelesen, aber irgendwas geht immernoch nicht:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
type
  // Definition
  TProzessbalken = class(TThread)
  private
    FProgressBar: TProgressBar;
  protected
    procedure Execute; override;
  public
    constructor Create(ProgressBar: TProgressBar);
  end;

ausblenden 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
  // Erstellen
  FProgressBar:= ProgressBar;
  FreeOnTerminate := True;
  inherited Create(False);
end;

procedure TProzessbalken.Execute;
var
  i: Integer;
begin
  // Ausführen
  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;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
var
  Prozessbalken: TProzessbalken;
begin
  Prozessbalken:= TProzessbalken.Create(PB);
  Prozessbalken.Resume; // Arbeiten
  IBSFTT.ExecuteScript;
  Prozessbalken.Suspend; // Pause


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 user profile iconNarses: Code- durch Delphi-Tags ersetzt
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 13.07.12 10:19 
Moin!

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakane Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: Fr 13.07.12 10:56 
Jetzt versteh ich gar nichts mehr :(

Kann jemand mein Code umbauen, das es funktioniert?
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 13.07.12 11:24 
Moin!

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
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

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakane Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: Fr 13.07.12 11:33 
Moderiert von user profile iconNarses: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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

_________________
Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10181
Erhaltene Danke: 1254

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 13.07.12 11:51 
Moin!

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
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. :?

user profile iconJakane hat folgendes geschrieben Zum zitierten Posting springen:
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 user profile iconbummi :beer: geht´s natürlich schon genauer, aber eine Schätzung wird das immer bleiben. :nixweiss: Die Frage ist halt, wie genau die wird. ;)

_________________
There are 10 types of people - those who understand binary and those who don´t.
Jakane Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 257



BeitragVerfasst: Mo 23.07.12 10:12 
Irgendwas scheint immernoch falsch zu sein :(

ausblenden 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;

ausblenden 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;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure _Parallel_Prozessbar(IBScript: TIBScript);
var
  ProzessScript: TProzessScript;
begin
  ProzessScript:= TProzessScript.Create(IBScript);
  ProzessScript.Resume; // Arbeiten
end;

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure TProzessScript.Execute;
begin
  ProzessFertig:= False;
  PIBScript.ExecuteScript;
  ProzessFertig:= True;
end;

ausblenden 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 user profile iconNarses: Code- durch Delphi-Tags ersetzt
Einloggen, um Attachments anzusehen!