2 Stimmen

Fenster bei Gewindestopp schließen

Ich habe eine Frage zu Fäden und Kontrollen. Ich habe einen modalen Dialog zur Synchronisierung erstellt. Es gibt drei Fortschrittsbalken und ein paar Beschriftungen. Wenn die Anwendung zum ersten Mal geöffnet wird, wird der Synchronisationsdialog geöffnet und die Aktualisierung durchgeführt. In der Show()-Methode des Dialogs habe ich drei verschiedene Threads erstellt. Jeder Thread steuert das Herunterladen der Daten, das Parsen von XML und das Einfügen in die Datenbank. Und zeigt dann den Fortschritt in der Fortschrittsleiste an. Alles, was beschrieben wurde, funktioniert gut.

Nun das Problem - ich möchte diesen Dialog automatisch schließen, wenn alle Elemente heruntergeladen, analysiert und in die Datenbank eingefügt wurden. Ich habe versucht zu prüfen, ob progressbar.position gleich progressbar.max ist und ich habe versucht zu prüfen, ob die Threads beendet sind, wenn ich mit dem progressbar Weg gehe, schließt sich der Dialog zu früh und ein progressbar ist nicht ganz beendet. Wenn ich mit der Thread-Prüfung Weg gehen, dann progressbars in der Mitte des Prozesses zu stoppen und das ist alles.

Vielleicht haben Sie es getan und sagen Sie dem Delphi-N00b, wie man es am besten macht.

Vielen Dank im Voraus...

5voto

jachguate Punkte 16748

Für diese einfache Sache können Sie das Thread OnTerminate-Ereignis (das im Kontext des Hauptthreads abläuft) verwenden, um eine "Thread Count"-Variable zu dekrementieren, die bei der Thread-Erstellung auf 3 initialisiert wird.

Wenn die Fadenzahl 0 erreicht, können Sie das Formular sicher schließen.

begin
  //..thread creation, stuff
  FThreadCount := 3;
  DownloadThread.OnTerminate := DecThreadCount;
  ParseThread.OnTerminate := DecThreadCount;
  InsertThread.OnTerminate := DecThreadCount;
  //resume threads and other stuff
end;

procedure TForm1.DecThreadCount(Sender: TObject);
begin
  Dec(FThreadCount);
  if FThreadCount = 0 then
    Close;
end;

2voto

Mason Wheeler Punkte 79858

Verwenden Sie Windows Vista oder Windows 7? Microsoft hat die Funktionsweise von Fortschrittsbalken in Vista geändert, so dass sie nicht mehr sofort an die angegebene Position springen, sondern sich allmählich dorthin bewegen. Das bedeutet, dass Ihr Fortschritt tatsächlich abgeschlossen sein kann, aber der Balken zeigt dies erst nach etwa einer Sekunde an, so dass es so aussieht, als sei das Dialogfeld geschlossen, bevor Sie fertig sind, insbesondere wenn der Balken eine geringe Anzahl von Fortschrittsschritten aufweist.

Es ist ein bisschen hässlich, aber Sie können dies umgehen, indem Sie eine Hilfsfunktion verwenden, die etwas wie dieses tut:

procedure UpdateProgressBar(bar: TProgressBar);
begin
  bar.StepIt;
  bar.Max := bar.Max + 1;
  bar.Max := bar.Max - 1;
end;

Dadurch wird sichergestellt, dass er sofort an die richtige Stelle springt.

EDIT: Details in Wie bringe ich TProgressBar dazu, nicht mehr zu verzögern?

1voto

David Heffernan Punkte 585606

Ich würde Ihre Threads dazu bringen, eine Nachricht an den Dialog zu senden, wenn sie abgeschlossen sind. Sobald alle drei Nachrichten eingegangen sind, können Sie den Dialog schließen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X