AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

"Bitte warten"-Formular korrekt anzeigen

Ein Thema von TheMiller · begonnen am 24. Aug 2010 · letzter Beitrag vom 26. Aug 2010
Antwort Antwort
Benutzerbild von Björn Ole
Björn Ole

Registriert seit: 10. Jul 2008
166 Beiträge
 
Delphi XE Professional
 
#1

AW: "Bitte warten"-Formular korrekt anzeigen

  Alt 26. Aug 2010, 02:59
Hab jetzt noch nicht genau den Aufbau deiner Idee geblickt, aber ich häng dir mal eine kleine Demo an.

Ausschnitt:
Delphi-Quellcode:
procedure TfrmMain.Button1Click(Sender: TObject);
var
  frmWait: TfrmWait;
begin
  // Wartefenster erstellen
  frmWait := TfrmWait.Create(nil);
  // Thread starten
  TWorkerThread.Create(frmWait).OnTerminate := OnWorkerThreadTerminate;
  // Wartefenster anzeigen
  frmWait.ShowModal;
end;
Und im Thread, der die Aufgaben erledigt, dann so:
Delphi-Quellcode:
procedure TWorkerThread.Execute;
begin
  // setzt mit Synchronize das Label im Wartefenster
  SetAction('Wichtige Berechnung');
  Sleep(2000);
end;
Sobald der Thread terminiert, wird das Wartefenster geschlossen.

Ich hoffe mal, das ist in etwa das, was du brauchst.
Angehängte Dateien
Dateityp: zip WaitForMe.zip (4,5 KB, 18x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#2

AW: "Bitte warten"-Formular korrekt anzeigen

  Alt 26. Aug 2010, 09:18
Danke für die Antwort.

Der Sinn meiner Idee - ob das klapp oder nicht sei dahingestellt - war, eine einfache Klasse zu haben, die für mich den Thread und das WaitForm erstellt und auch wieder freigibt. So muss ich mich jedesmal selbst um den Thread etc. kümmern.

Der Unterschied unserer Versionen scheint zu sein, dass in deiner die Berechnungen im Thread durchgeführt werden.
Bei mir werden die Berechnungen im MainThread durchgeführt und existierten, bevor mir die Idee mit dem "Bitte-Warten"-Fenster kam. D.h, mein Thread soll so lange das Form anzeigen und aktualisieren, bis die Wrapper-Klasse den Status "Finished" erreicht hat.

Aber da liegt glaub ich das Problem. Während der MainThread die Berechnung durchführt, ist er blockiert und kann auch nicht das Warten-Fenster neuzeichnen, richtig?

Das würde auch bedeuten, dass ich alle Aktionen, die das Fenster benutzen sollen, in einen Thread verschoben werden müssen und ich so das Programm komplett umstellen darf... auch richtg?

Danke
  Mit Zitat antworten Zitat
blauweiss

Registriert seit: 19. Jun 2007
142 Beiträge
 
#3

AW: "Bitte warten"-Formular korrekt anzeigen

  Alt 26. Aug 2010, 10:42
Hallo DJ-SPM,

das hat jetzt nichts mit deinem eigentlich Problem zu tun, nur ein Hinweis:
Randomize soll in einem Programm nur 1-mal aufgerufen werden.
Du rufst es x-mal in einer Schleife auf.....
Delphi-Quellcode:
  for i:=0 to 100000 do
  begin
    randomize();
Gruss,
blauweiss
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#4

AW: "Bitte warten"-Formular korrekt anzeigen

  Alt 26. Aug 2010, 11:46
Ja ich weiß

Das war nur, weil die Schleife sowie nur den Testzwecken dient und ich, als ich es gemerkt habe, keine Lust mehr hatte, es umzuändern (da eh nur Test)

Aber trotzdem danke für den Hinweis
  Mit Zitat antworten Zitat
Benutzerbild von Björn Ole
Björn Ole

Registriert seit: 10. Jul 2008
166 Beiträge
 
Delphi XE Professional
 
#5

AW: "Bitte warten"-Formular korrekt anzeigen

  Alt 26. Aug 2010, 12:34
Während der MainThread die Berechnung durchführt, ist er blockiert und kann auch nicht das Warten-Fenster neuzeichnen, richtig?
Genau. Grundsätzlich sollte gelten, dass der Main Thread für die Oberfläche zuständig ist und alle aufwendigeren Berechnungen in einen weiteren Thread ausgelagert und Status-Meldung o.ä. synchronisiert an den Main-Thread geschickt werden.

Der Unterschied...
...ist mir auch erst nach meiner Antwort aufgefallen, hätte ich früher sehen müssen.

Als Alternative zur Auslagerung der Berechnungen in einen neuen Thread könntest du, wie rollstuhlfahrer hier früher schon erwähnt hat, in einem Thread das Warte Fenster nonVCL erstellen. So könntest du dann z.B. mit PostThreadMessage den Warte-Fenster-Thread über Updates benachrichtigen, während der Main Thread am werkeln ist. Schätze ab, was dir mehr Arbeit macht.

Geändert von Björn Ole (26. Aug 2010 um 12:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von TheMiller
TheMiller

Registriert seit: 19. Mai 2003
Ort: Gründau
2.480 Beiträge
 
Delphi XE7 Architect
 
#6

AW: "Bitte warten"-Formular korrekt anzeigen

  Alt 26. Aug 2010, 22:38
Hallo,

ich habe nun also in den sauren Apfel gebissen und die Aufgaben in einen Thread ausgelagert (bzw. das werde ich alles nach und nach machen).

Mein Warten-Formular und der Thread dazu steht und funktioniert. Meine Wrapper-Klasse wollte ich dennoch behalten. So ergibt sich der unten aufgeführte Code.

Ich habe also eine Wrapper-Klasse, die die Warten-Form anzeigt und den Thread startet. Zuvor wird der Wrapper-Klasse gesagt, welche Aktion der Thread zu erledigen hat. Der Thread startet und führt die für die Aktion hinterlegte Berechnung durch. Danach gibt sich die Klasse über den Thread wieder frei.

Wer's haben mag, darf es gerne nutzen. Schaut euch bitte meinen Code an und sagt, was positiv und was negativ ist. Danke..! (Achso: Bisher gab's keine Probleme bez. VCL, AVs etc.)

Anwendung der Wrapper-Klasse (Darstellen eines Warten-Bildschirms)
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  wu: TWaitUtils;
begin
  //Erstellt ein WaitUtil-Objekt, zeigt das Fenster an
  wu:=TWaitUtils.Create;

  //Erstellt einen Thread, sagt ihm was zu tun ist und lässt den Dingen seinen lauf
  wu.InitWaitThread(taStoreAttachment);

  //Freigeben nicht nötig, geschieht automatisch (laut FastMM4 alles OK).
end;
Und hier das, was wie im Hintergrund passiert (Auszug)

Delphi-Quellcode:
type
  TThreadActions = (taStoreAttachment, taLoadAttachment);

{************** TWaitThread ***************}
procedure TWaitThread.Execute;
begin
  case (Action) of

    taStoreAttachment:
    begin
      StoreAttachment;
    end;

    taLoadAttachment:
    begin

    end;
    
  end;
end;

{************** TWaitUtils ***************}
constructor TWaitUtils.Create;
begin
  InUse:=False;
  WartenForm:=TfrmWarten.Create(nil);
  Thread:=TWaitThread.Create(True);
  Thread.WaitFormular:=WartenForm;
  Thread.FreeOnTerminate:=True;
  Thread.WaitUtilObject:=Self;
  WorkerThread:=Thread;
  WorkerThread.OnTerminate:=ThreadTerminate;
end;

procedure TWaitUtils.InitWaitThread(ta: TThreadActions);
begin
  InUse:=True;
  ShowWaitForm;

  //Welche Aktion soll der Thread ausüben?
  Thread.Action:=ta;

  //Thread ins Rollen bringen
  Thread.Resume;
end;

procedure TWaitUtils.ThreadTerminate(Sender: TObject);
begin
  InUse:=False;
  with (Sender as TWaitThread).WaitFormular do
  begin
    Close;
  end;

  //Das Warten-Formular freigeben
  DestroyWaitForm;
  
  //Das WaitUtilObjekt wieder freigeben
  Thread.WaitUtilObject.Free;
end;
Ich häng's hier nochmal an, vielleicht mögt ihr es nutzen oder mal "Korrekturlesen"

Danke!
Angehängte Dateien
Dateityp: txt Warten.txt (3,3 KB, 18x aufgerufen)

Geändert von TheMiller (26. Aug 2010 um 22:42 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:45 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