Backgroundworker - ReportProgress

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Pry.

    Backgroundworker - ReportProgress

    Hallo,

    ich habe jetzt schon einige male Versucht mit dem BGW zu arbeiten, allerdings bin ich zu oft auf ein Problem gestoßen.
    Ansatz war der Code von Mike69.

    Ich habe nun einmal ein kleines Testprogramm gebaut, um mir den BGW nochmal anzuschauen:

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Public WithEvents bgw As New BackgroundWorker
    4. Public a As Decimal = 0
    5. Public pz As Integer 'Prozent
    6. Public Zahl As Integer = 1000000
    7. Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    8. For i = 0 To Zahl
    9. a += i
    10. pz = (i / Zahl) * 100
    11. If pz Mod 1 = 0 Then
    12. bgw.ReportProgress(pz)
    13. End If
    14. Next
    15. bgw.ReportProgress(100)
    16. End Sub
    17. Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
    18. ProgressBar1.Value = e.ProgressPercentage
    19. 'Label1.Text = a.ToString
    20. End Sub
    21. Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
    22. PictureBox1.Visible = False
    23. Label1.Text = a.ToString
    24. End Sub
    25. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    26. bgw.WorkerReportsProgress = True
    27. bgw.WorkerSupportsCancellation = True
    28. End Sub
    29. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    30. PictureBox1.Visible = True
    31. Label1.Text = "Bitte warten..."
    32. bgw.RunWorkerAsync()
    33. End Sub
    34. End Class


    Ich lasse einfach nur eine lange Schleife laufen, welche die einzelnen i-Werte zusammenzählt. Also nichts großartiges. Jedoch möchte ich dabei einen ProgressBar ansteuern, welche die % des Vorgangs (Ganzzahlig) anzeigt. Jetzt habe ich allerdings das Problem, dass meine Form dennoch "hängt" und keine Rückmledung gibt. Ich kann mir nur vorstellen, dass die Bar hierbei zu oft aktualisiert wird, so dass sich die Form weghängt. Aber das würde ja dem BGW widersprechen, oder mache ich was falsch? Ich hoffe ihr versteht, was ich für ein Problem habe :)

    Viele Grüße,
    Pry
    Dateien umbenennen und nummerieren - nichts leichter als das!

    Basic File Renamer: 100%

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Pry“ ()

    Hallo Pry,

    Ich kann mir nur vorstellen, dass die Bar hierbei zu oft aktualisiert wird, so dass sich die Form weghängt.

    so ist es.

    Die Form hat keine Zeit sich neu zu Zeichnen, denn du kommst viel zu schnell mit dem neuen Wert daher.

    Bau mal pausen ein - dann klappt das auch.

    Gruss

    mikeb69
    am besten wäre es erst nach jeder 10ten oder 100ten Berechnung einen neuen Wert zu liefern, dann sollte auch die Berechnung nicht so stark verlangsamt werden...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Du lieferst erst alle 10.000 Iterationen einen neuen Wert, da ja value kein Double sondern ein Integer Wert ist. Das heisst Du knallst mit Deinem Progressbar Update 1 Mio Windows Messages raus die das Betriebssystem so schnell nicht verkraften kann.

    Bau mal Thread.Sleep(1) nach Deinem ReportProgress ein, und geh 1-2 Zehnerpotenzen runter, dann kannst Du auch Deinen Label-Zähler problemlos anzeigen lassen.
    Hallo,

    danke für die Antworten. Ich habe

    VB.NET-Quellcode

    1. Public pz As Integer
    in

    VB.NET-Quellcode

    1. Public pz As Decimal
    geändert.

    Das ist natürlich dumm gelaufen, weil "pz" die ersten 10.000 Durchläufe auf "0" steht. Wie dem auch sei, die Änderung hat bewirkt, dass es jetzt auch rennt. Das Benutzen von Thread.Sleep geht natürlich auch, ebenso wie

    VB.NET-Quellcode

    1. If pz Mod 10 = 0 Then
    Beim Ändern der If-Anweisung werden die Aktualisierungsschritte natürlich weniger und die ProgressBar füllt sich nicht mehr so schön flüssig :)

    Vielen, vielen Dank für die Denkanstöße!

    Grüße,
    Pry
    Dateien umbenennen und nummerieren - nichts leichter als das!

    Basic File Renamer: 100%

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Pry“ ()

    Hallo,

    eine Frage habe ich dazu noch. Ich habe einige WMI-Abfragen eines Programms im BGW laufen lassen. In einer anderen Version (selbe Abfragen, nicht im BGW) nicht. Wenn ich nun die Abfragezeiten miteinander vergleich, fällt mir auf, dass die Version mit dem BGW länger braucht, um das Ergebnis auszugeben. Wieso ist dem so?

    Viele Grüße,
    Pry
    Dateien umbenennen und nummerieren - nichts leichter als das!

    Basic File Renamer: 100%
    das ist so, da der Thread erstellt und gestartet werden muss...
    Außerdem habe ich mal gelesen(auf Codeproject), dass Windows zwar die Threads schnell erstellt, aber diese langsamer sind, als z.B. bei Linux, bei Linux jedoch brauchen sie länger zum erzeugen, was davon besser ist, wird wohl auch je nach Situation sein...
    hinzu kommt, dass bei der Ausgabe der Informationen der Thread mit dem GUI Thread Synchronisiert werden muss, da diese Threads nicht direkt miteinander kommunizieren könnnen...bei einem BGW funktioniert dies über einen PostAsync, welcher natürlich auch noch Zeit beansprucht...
    Ich denke es ist ok, wenn man dinge, die nicht solange brauchen(ein paar Sekunden) im GUI Thread laufen...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---