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

Der Code  - (Visual Basic, vb)

2 Antworten

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.

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