Ich verwende einen Fortschrittsbalken, um dem Benutzer anzuzeigen, wie weit der Prozess fortgeschritten ist. Es hat 17 Stufen und kann abhängig vom Wetter (gut, Datenbank) zwischen 5 Sekunden und zwei oder drei Minuten dauern.
Ich hatte kein Problem damit in XP, der Fortschrittsbalken ging gut, aber beim Testen in Vista fand ich, dass es nicht mehr der Fall ist.
Zum Beispiel: wenn es näher an 5 Sekunden dauert, könnte > es ein 1/3 des Weges machen, bevor es verschwindet, weil es fertig ist. Obwohl es bei 17 von 17 ist, zeigt es es nicht. Ich glaube, das liegt an der Animation, die Vista auf Fortschrittsbalken setzt und die Animation kann nicht schnell genug enden.
Weiß jemand, wie ich das korrigieren kann?
Hier ist der Code:
Dies ist der Teil, der den Fortschrittsbalken aktualisiert. Warten ist das Formular mit dem Fortschrittsbalken.
%Vor%Hier ist das wartende Formular:
%Vor% Versuchen Sie, den Aufruf der Methode waiting.setProgess()
aufzurufen, da waiting
in einem anderen Thread zu leben scheint. Dies wäre ein klassischer cross-Thread-Aufruf (worüber der Compiler Sie warnt, wenn Sie ihn lassen).
Da Control.Invoke
etwas unhandlich ist, verwende ich normalerweise eine Erweiterungsmethode, die es mir erlaubt, einen Lambda-Ausdruck zu übergeben:
.
%Vor%Vista hat beim Aktualisieren des Fortschrittsbalkens einen Animationseffekt eingeführt - er versucht, sanft von der vorherigen Position zur neu eingestellten Position zu scrollen, was zu einer unangenehmen Zeitverzögerung beim Update des Controls führt. Die Verzögerung ist am auffälligsten, wenn Sie einen Fortschrittsbalken in großen Schritten springen, sagen wir von 25% auf 50% in einem Sprung.
Wie ein anderes Poster gezeigt hat, können Sie das Vista-Thema für die Fortschrittsleiste deaktivieren und es wird dann das Verhalten von XP-Fortschrittsbalken nachahmen.
Ich habe eine andere Problemumgehung gefunden: Wenn Sie den Fortschrittsbalken rückwärts setzen, wird er sofort zu diesem Ort malen. Wenn Sie also von 25% auf 50% springen möchten, würden Sie die (zugegeben hackische) Logik verwenden:
%Vor%Ich weiß, ich weiß - es ist ein dummer Hack - aber es funktioniert!
Der Grund für dieses ganze Chaos ist der interpolierende Animationseffekt von Vista und W7. Es hat absolut nichts mit Thread-Blockierungsproblemen zu tun. Der Aufruf von setProgress () oder das direkte Setzen der Value-Eigenschaft löst einen Animationseffekt aus, der erklärt, wie man schummelt:
Ich habe einen Hack gemacht, um das Maximum nach einem festen Wert zu setzen. Die maximale Eigenschaft löst den Effekt nicht aus, sodass Sie den Fortschritt mit sofortiger Reaktion frei bewegen können.
Denken Sie daran, dass der tatsächlich angezeigte Fortschritt gegeben ist durch: ProgressBar.Value / ProgressBar.Maximum. Aus diesem Grund wird das folgende Beispiel den Fortschritt von 0 auf 100 verschieben, wie von i wiederholt:
%Vor%Ich habe einige Skalierungsfaktoren hinzugefügt, die selbsterklärend sein sollten:
%Vor% Es klingt , als würden Sie alles auf dem UI-Thread tun und somit die Nachrichtenpumpe nicht freigeben. Hast du versucht, das Smoothing wie BackgroundWorker
und% ProgressChanged
zu verwenden? Ein Beispiel finden Sie MSDN .
BackgroundWorker
ist ideal zum Laden von externen Daten - aber beachten Sie, dass Sie keine Datenbindung durchführen sollten, bis Sie zum UI-Thread zurückkehren (oder verwenden Sie einfach Invoke
/ BeginInvoke
, um die Arbeit an die UI-Thread).
Ich verwende Mark Lansdowns ausgezeichnete Antwort als eine Erweiterungsmethode für das ProgressBar-Steuerelement.
%Vor%Oder Sie können es auch so machen, dass die ProgressBar value -Eigenschaft nur zweimal statt dreimal gesetzt wird:
%Vor%Rufen Sie es einfach mit der Erweiterungsmethode für ein ProgressBar-Steuerelement auf:
%Vor%Wenn Sie wirklich möchten, können Sie auch die aktuelle Windows-Umgebung überprüfen und nur den Hack-Codeabschnitt für Windows Vista + ausführen, da die ProgressBar von Windows XP nicht über die langsame Fortschrittsanimation verfügt.
Erstens. Ich würde die Option CheckForIllegalCrossThreadCalls niemals deaktivieren.
Sekunde. Fügen Sie eine Aktualisierung () hinzu, nachdem Sie den Fortschritt aktualisiert haben. Nur weil du in einem anderen Thread arbeitest, bedeutet das nicht, dass dein GUI-Thread zur Aktualisierung übergeht.
Ich habe das gleiche Problem. Ich habe ein Formular mit mehreren Fortschrittsbalken (der erste ist zum Beispiel Datei x / n, der untere ist Aufgabe y / m) Der obere Fortschrittsbalken aktualisiert TIMELY nicht, während der untere Fortschrittsbalken dies tut Programmatisch aktualisiere ich, invalidate, explizite Prozessmeldung, Refresh oder Sleep repariert es nicht. Lustige Sache ist, dass der untere Fortschrittsbalken und andere Komponente (Zeit verstrichener Text) in Ordnung ist. Dies ist ein reines Vista + Thema Problem (Animationen wie zuvor vorgeschlagen, XP oder Vista mit klassischen Thema funktioniert gut. Beim Anzeigen eines Meldungsfelds, nachdem der obere Fortschrittsbalken auf 100 (programmgesteuert, nicht visuell) gereist ist, sehe ich zuerst das Meldungsfeld und dann sehe ich, wie der Fortschritt abgeschlossen wird
Ich habe festgestellt, dass SetWindowTheme (ProgressBar.Handle, '', ''); wie erklärt auf Deaktivieren der Fortschrittsbalken-Animation auf Vista Aero funktioniert (aber ich habe jetzt alte Stil Fortschrittsbalken)
Tags und Links c# windows-vista progress-bar .net-3.5