Frage von RayYago, 49

Visual Basic Progressbar mit For Schleife überspringt immer 10 &?

Hallo erstmal, ich bin noch recht neu in Visual Basic bzw. in der Programmierung und finde mich gerade ein. Ich bin dabei eine Progress bar zu erstellen die sich selber beim Knopfdruck auffüllt und dabei in einem Label die Prozent wiedergibt wie viel Prozent schon gefüllt sind. Ich habe es so eingestellt das die Progress bar sich immer in 10ner Schritten füllt. Nun habe ich aber das Problem das er immer die 90% überspringt, sprich es läuft 10 20, 30, 40 ,50 ,60, 70, 80, 100 . Das kann ja nicht richtig sein. Ich habe es mit der Do Loop While und mit der Do until Schleife auch schon probiert. immer das gleiche Problem. Den Code habe ich hier einmal als Bild mitgeschickt. Meine Form besteht nur aus einer Progress bar, einem Label und einem Button. Ich hoffe jemand kann mir helfen, ich krieg es einfach nicht hin.

Antwort
von CrystalixXx, 16

Zuerst zu deinem Problem: Application.DoEvents steht an der falschen Stelle. Wenn dich die Erklärung für das Verhalten interessiert, dann lies weiter, ansonsten springe zum nächsten Absatz nach der Liste. Schritt für Schritt sieht der Ablauf so aus:

  • Erster Durchlauf: Du setzt den Wert auf 10 und weist diesen Wert dem Label zu. Das Label hat nun von Windows eine Anforderung zum Neuzeichnen erhalten und wird diese ausführen, sobald die MessageQueue verarbeitet wird. (Das passiert noch nicht, weil der aktuelle Thread noch in der For-Schleife arbeitet.)
  • Im zweiten Durchlauf setzt du den Wert auf 10 und erlaubst die Abarbeitung der MessageQueue durch Application.DoEvents. Das Label darf nun seinen Inhalt aktualisieren und zeigt den Wert 10 an. Erst dann weist du dem Label den neuen Wert 20 zu. Gleiches Spiel: die Anforderung zum Neuzeichnen landet in der MessageQueue und wird bei der nächsten Abarbeitung ausgeführt. Aber auch das passiert erst im nächsten Durchlauf.
  • Im vorletzten Durchlauf ist der Wert der ProgressBar 90 und das Label darf dann erst seine 80 aus der vorherigen Anforderung zeichnen.
  • Im letzten Durchlauf passiert das gleiche. Allerdings ist der Thread danach frei (kein Thread.Sleep) und kann sofort die MessageQueue erneut abarbeiten und somit die 100 anzeigen. Die 90 wird also vorher angezeigt, aber nur für den Bruchteil einer Sekunde (wenn überhaupt).

Wenn du Application.DoEvents nach der Wertzuweisung des Labels schreibst, funktioniert es wie gewollt.

Nun zum anderen Problem: Nichts ist nerviger als ein simulierter Fortschritt. Eine ProgressBar, die ihren Wert in Abhängigkeit einer (zur Entwurfszeit) definierten Zeit verändert hält den gesamten Programmablauf auf und hat ohne Multithreading wenig Sinn.

Antwort
von TzorpHD, 6

Versuche es mal damit:

For i as integer = 1 to 10
       ProgressBar1.value = i * 10
       Label1.Text = Str(Int(i * 10)) + "%"
       Application.DoEvents()
       System.Threading.Thread.sleep(100)
Next

Lg Tzorp

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten