ProgressBar zu "langsam"

Karl-Heinz

Grünschnabel
Hallo,

ich sende einen String über die serielle Schnittstelle (Zeichen für Zeichen, Baudrate: 9600). Hierbei wird nach dem Senden
eines Zeichens auch der Wert (Value) einer ProgressBar um eins erhöht (ProgressBar.Maximum = String.Length). Nun kommt
es immer vor, dass der String bereits vollständig gesendet wurde, die ProgressBar aber noch nicht vollständig "ausgefüllt".
Ich habe dann folgende Testzeilen mit einem Timer geschrieben um dem Problem vielleicht auf die Spur zu kommen.
Ich verwende VIsual Basic 2008.

Private Sub Button9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button9.Click
PrgrBr.Maximum = 60
PrgrBr.Minimum = 0
PrgrBr.Step = 1
Index = 0
Timer1.Start()
End Sub

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Index += 1
PrgrBr.PerformStep()
If Index = 60 Then
Timer1.Stop()
Button9.BackColor = Color.Green
PrgrBr.Value = 0
End If
End Sub

Das Verhalten hier ist genau gleich wie bei meinem Programm das einen String sendet.
Die ProgressBar wird hierbei gelöscht (Index = 60) obwohl noch nicht vollständig farbig ausgefüllt.
Weis hier vielleicht jemand Rat bzw. hat jemand einen Tip für mich?
Es sieht irgendwie "blöd" aus, wenn das Empfangsgerät meldet "String empfangen" und die ProgressBar
noch nicht vollständig ausgefüllt ist.

Vorab Danke!
Gruß
Karl-Heinz
 
Zuletzt bearbeitet:
Das heist dein String, der die Daten beinhaltet ist auch immer 60 Zeichen lang?

Wenn das so ist, müsstest du nur in der Entwurfsansicht bei der Progressbar den Maximum-wert auf 60 setzen, startwert auf 0 und dann kannst du noch die steps verändern.

Wo änderst du das maximum der Progressbar? während der Laufzeit, also nachdem die Form schon erstellt ist? oder direkt in der form.designer.cs?

änders entweder so, wie ich es vorgeschlagen hab, oder manuel in der form.designer.cs.
(Dort dan irgendwo den generierten code aufklappen und passendes Steuerelement raussuchen und ändern).

EDIT: oh, hab grad gelesen, dass du auf Buttonklick die Progressbar veränderst, das klappt nicht, weil die Bar standartmäsig bis 100 geht, wenn du sie während der Laufzeit veränderst, ohne ohne in irgendeiner weise einen Refresh durchzuführen, passiert auch nix;) machs lieber wie ich es gesagt hab, dan wird alles vor Erstellen der Form geladen.

MfG
 
Zuletzt bearbeitet:
Hallo,

im Programm in dem ich den String sende, setze ich das Maximium der ProgressBar mit String.Length
auf die jeweilige Länge des Strings (kann unterschiedlich sein). Ich ändere das Maximum während der Laufzeit (die Länge
des zu ändernden Strings kann sich auch während der Laufzeit ändern (TextBox).
Das "Programm" das ich angefügt habe ist unabhängig von meinem Programm das den String sendet.
Ich habe es nur erstellt um das Verhalten der ProgressBar zu testen. Aber auch hier hat sich die
ProgressBar so verhalten...

Gruß
Karl-Heinz
 
Zuletzt bearbeitet:
achso, hm, also ich habs grad getestet mit
C++:
progressbar1.Maximum = 500;
und es hat wunderbar geklappt.

Ich weis nicht genau, ob das Attribut Locked damit zu tun hat, doch überprüf mal ob dieses auf standart FALSE ist.

Ansonsten probier mal nach dem ändern des Maximums die Methode refresh aufzurufen:
C++:
progressbar1.Refresh();

EDIT: nach einigem testen hab ich nun das gleiche Problem hinbekommen^^ Also, das Problem tritt nur auf, wenn die Bar schon etwas dartellt. Suche noch nach einer Lösung

EDIT2: also bi mir funktioniert super wenn ich einfach normal den Wert Maximum neu setze.
Was genau passiert den immer? malt er die Bar immer gleichlang? oder immer unterschiedlich, aber nicht bis zum Ende?
 
Zuletzt bearbeitet von einem Moderator:
Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Index += 1
    PrgrBr.PerformStep()
    If Index = 60 Then
        Timer1.Stop()
        Button9.BackColor = Color.Green
        PrgrBr.Value = 0
    End If
End Sub
Du setzt die ProgressBar in fast dem selben Moment, wo sie ihr Maximum (60) erreicht hat, wieder auf Null zurück. Damit ist es für das menschliche Auge nicht sichtbar, dass die ProgressBar tatsächlich mal bei 60 angekommen war. Ist dir das bewusst?

Ansonsten habe ich das Problem noch nicht richtig verstanden. Änderst du den Max-Wert der ProgressBar, während du bereits "sendest" und deshalb aktualisiert sich die ProgressBar nicht ordentlich?

Die Locked-Eigenschaft ist nur für den Designer relevant. Es sagt aus, ob ein Steuerelement zur Entwurfszeit verschoben werden darf oder ob es "festgehalten" werden soll, damit man es nicht aus Versehen verschiebt.
 
Zuletzt bearbeitet:
Im Betreff sprichst du von zu langsam.
Wie groß ist den in der Regel das Maximum der Progressbar?

Das einzige Problem das ich sehe ist wenn das Maximum zu groß ist dann kommt ev. keine Rückmeldung mehr von der Form.
Da diese ja immer mit dem Neuzeichnen der Progressbar zu tun hat.

Ansonstonen wie Shakie, bitte genauer erklären, ev. sogar original Code posten.
 
Hallo,

vielen Dank für die bisherigen Antworten und sorry das ich mich jetzt erst wieder melde.
Also hier der entsprechende Ausschnitt meines Programms, sowie ein
Screenshot (unten):

Code:
Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles KonfDat_senden.Click
        Dim AnzZeiKonfDat As Integer
        Dim IndexKonfDat As Integer
        IndexKonfDat = 0
        AnzZeiKonfDat = KonfDat.Length()              'Anzahl der Zeichen ermitteln
        PrgrBr.Maximum = AnzZeiKonfDat             'ProgressBar Maximum auf die Anzahl zu sendenden Zeichen setzen        
        PrgrBr.Step = 1
        Status.Text = "Sende Konfigurationsdatei"    'Status Text aktualisieren
        For I = 0 To (AnzZeiKonfDat - 1)                       'Schleife bis alle Zeichen des Strings gesendet
            PrgrBr.PerformStep()                                     'Wert ProgressBar um 1 erhöhen
            PrgrBr.Refresh()
            SerialPort1.Write(KonfDat(IndexKonfDat))
            IndexKonfDat += 1
        Next I
->    Status.Text = "Konfigurationsdatei vollst. gesendet"     'Status Text aktualisieren
End Sub

Ich habe in der Zeile mit dem "->" einen Breakpoint gesetzt und einen Screenshot erzeugt.
Der String (KonfDat) ist zu diesem Zeitpunkt bereits vollständig gesendet. Der String in diesem Beispiel
hatte eine Länge von 467 Zeichen. Somit wurde das ProgressBar Maximum auf 467 gesetzt.
Zum Zeitpunkt des Breakpoints hat Value der ProgressBar zwar das Maximum (also
467) erreicht, optisch ist dies jedoch an der ProgressBar nicht zu erkennen (siehe Screenshot).
Ist dies normal oder mache ich hier etwas grundlegendes falsch?

Gruß
Karl-Heinz
 

Anhänge

  • Screenshot ProgressBar.jpg
    Screenshot ProgressBar.jpg
    42,7 KB · Aufrufe: 123
Hi,

Versuch mal die Verarbeitung, also das schreiben auf den Port, in einen Thread auszulagern und die Oberfläche holt sich mit einem Timer den Fortschritt der Verarbeitung.

Gruß
Col.Blake
 
Ich habe es ausprobiert den Fehler nachzubauen, aber ich habe es nicht hinbekommen. Bei mir hat sich die ProgressBar immer ordentlich aktualisiert.
@colblake: bin mal gespannt ob das was bringt. Denn eigentlich ist die Control.Refresh-Methode direkte Anweisung an das Control sich neu zu zeichnen. Siehe MSDN. Aber in anderen Foren schreiben die Leute, dass ein Thread wohl die Lösung des Problems wäre.
@Karl-Heinz:
Probier mal ob ein einfaches
Code:
Application.DoEvents
nach PrgrBr.Refresh() funktioniert.
Falls nichts hilft:
kannst du ein kompilierbares Minimalbeispiel posten, damit ich den Fehler mal reproduzieren kann?
 
Hi,

ich hab das deshalb beschrieben, weil ich folgendes Vermute:

Da die Methode im selben Thread läuft wie die GUI, wird die GUI wärend es Ablaufes nicht oder nicht ausreichend aktualisiert. Da die Progressbar ein Teil der GUI ist, ist sie auch betroffen.
Bin mir aber nicht sicher, ob man da unbedingt einen Thread benutzen muss, oder ob es in DOTNET nicht auch anders geht. Ich muss das mal ausprobieren.

Gruß
Col.Blake
 

Neue Beiträge

Zurück