progressbar in abhängigkeit vom thread füllen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von Seyphedias.

    progressbar in abhängigkeit vom thread füllen

    Hallo Community,

    das hier ist mein erster Post :). Ich schreibe euch, weil ich durch googeln wirklich nicht weiter komme.

    Ich habe folgendes (wahrscheinlich einfaches) Problem:
    Ich habe den MainThread (GUI). Durch klicken auf einen Button erscheint ein Fenster mit einer Progressbar, wenn die Form erscheint startet ein neuer Thread für eine aufwändige Berechnung.
    da dieser Thread mal mehr, mal weniger zeit in Anspruch nimmt, möchte ich die Progressbar so füllen lassen, dass Sie bei 100% ist, sobald der Thread fertig ist (NICHT VORHER). Während der Thread läuft, bzw. berechnet soll sich die progressbar füllen, um den User zu signalisieren, dass das Programm noch arbeitet.


    Das Befüllen der progressbar habe ich mit einem Backgroundworker realisiert. Klappt auch soweit, aber leider nur statisch. Das bedeutet, die progressbar ist zu langsam, oder zu schnell. Ich möchte allerdings vermeiden, meine progressbar zu langsam zu füllen, und dann sobald der Thread fertig ist sie auf 100 zu stellen, das würde einen großen Sprung des Balkens bedeuten.

    Prinzipiell möchte ich einfach nur den Backgroundworker, der in seinem DoWork Event die performStep Methode der Progressbar aufruft, an den Thread koppeln.

    Vielen dank schonmal im vorraus für Vorschläge.


    Grüße
    Seyphedias
    Willkommen im Forum. :thumbup:

    Seyphedias schrieb:

    Backgroundworker ... an den Thread koppeln
    ist Tinnef.
    Lass den Thread einfach ein Event senden, dass Du invoken musst, da es aus einem anderen Thread kommt.
    Gugst Du Alles über Events.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Seyphedias schrieb:

    den Backgroundworker an den Thread koppeln.
    Da gibts nix zu koppeln - ein BGW ist doch schon an einen Thread gekoppelt (was immer das heissen mag).
    Also das BGW_DoWork-Event läuft im NebenThread, und da kannst du deine Berechnungen ausführen.
    Und zwischendrin halt gelegentlich BGW.ReportProgress() aufrufen - aber das weisste ja schon, oder? (bitte die Frage beantworten)
    Lass den Thread einfach ein Event senden, dass Du invoken musst, da es aus einem anderen Thread kommt.


    Danke für die Antwort. Verstehe aber nicht so ganz was du meinst, meinst du ich soll überall in meinem thread nach jeder Zeile oder so ein event schmeißen, der sagt, "ich bin jetzt bei zeile 1/10000" oder wie meinst du das?

    Danke :)

    Da gibts nix zu koppeln - ein BGW ist doch schon an einen Thread gekoppelt (was immer das heissen mag).
    Also das BGW_DoWork-Event läuft im NebenThread, und da kannst du deine Berechnungen ausführen.
    Und zwischendrin halt gelegentlich BGW.ReportProgress() aufrufen - aber das weisste ja schon, oder? (bitte die Frage beantworten)



    die berechnung läuft in einem Thread und soll nicht im BGW laufen. und es ist mir zu aufwändig bei 5000 zeilen code immer wieder mal die progressbar zu füllen.
    Des weiteren will ich nicht, das irgendwelche forms berechnungen durchführen. der bgw soll dafür zuständig sein die progressbar zu füllen..

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

    Seyphedias schrieb:

    so ein event schmeißen
    So ungefähr.
    Sieh Dir dies mal an, allerdings ist da noch kein Empfänger dabei:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public Event MyThreadEvent(ByVal sender As System.Object, ByVal e As MyEventArgs)
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. Dim value = 42
    5. ' hier wird der Event gesendet
    6. RaiseEvent MyThreadEvent(Me, New MyEventArgs(value))
    7. End Sub
    8. End Class
    9. Public Class MyEventArgs
    10. Inherits EventArgs
    11. Public Property Percent As Integer
    12. Public Sub New(value As Integer)
    13. Me.Percent = value
    14. End Sub
    15. End Class

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Seyphedias schrieb:

    die berechnung läuft in einem Thread und soll nicht im BGW laufen.
    ja, kein problem!
    bzw doch, denn eine berechnung kann sowieso nicht im bgw laufen.
    der bgw feuert ein Event bgw_Dowork(), und wer das Event behandelt, der läuft im NebenThread.
    Er läuft nicht im bgw, sondern im NebenThread des Bgw - dazu ist ein bgw nunmal da.

    Wenn du zusätzlich zum Bgw noch einen separaten Thread erstellst, dann hast du einen Thread zuviel.
    Und daher kommt auch dein Problem, dass diese "nicht gekoppelt" seien.

    Man koppelt keine Threads, Thread koppeln gibts garnet. Wenn der Progress-Fortschritt an die Berechnung gekoppelt sein soll, dann ruf den Fortschritt von der Berechnung aus auf.
    Wieso habe ich dann einen thread zu viel? Die Berechnung soll nicht im Hauptthread stattfinden, da sie das Programm zum "Einfrieren" bringt (Main Form wird ausgegraut und reagiert nicht mehr). Daher Folgender ablauf: In der Mainform auf Button drücken -> modeler Dialog erscheint in dem ein Abbrechen Button (killt den Thread), sowie die Progressbar zu sehen ist. Sobald die Form Geladen ist, startet der Thread und führt seine Berechnung aus, dabei bleibt dann das Programm handlungsfähig, bzw der einzige button, den man drücken kann ist der Abbrechen button. Und jetzt kommt der BGW, der einfach die Progressbar parallel zum Berechnungsthread füllen soll.

    Wieso habe ich jetzt einen Thread zu viel? ?(

    Danke für deine Antworten :)

    Seyphedias schrieb:

    Wieso
    Weil Du einen Berechnen-Thread hast sowie einen Prozent-BGW.
    Pack die Prozent-Logik in den Berechnen-Thread und sieh oben weiter bei den Events.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Pack die Prozent-Logik in den Berechnen-Thread und sieh oben weiter bei den Events.


    Ja das könnte ich machen, aber dann muss ich das Event ja alle paar Zeilen Code ausführen, was total aufwändig ist.
    um eine PB zu füllen brauchst du keinen Backgroundworker mit seinem NebenThread. Das macht ein Timer besser.


    die idee gefällt mir, wie meinst du das genau? Ich kann nicht vorhersehen, wie lange der thread Arbeitet, zu mal auch noch eine Minimierung einer Zielfunktion dessen Bestandteil ist.

    Ich greife außerdme auf dem BGW zurück, weil ich mit Ihm in seinem RunWorkerComplete Event einfach die Form schließen kann, nachdem alle berechnungen durchgelaufen sind, ohne noch irgendwo hin zu klicken.

    Seyphedias schrieb:

    was total aufwändig ist.
    Wieso?
    Mach Dir eine Prozedur, die das macht, und die kannst Du aufrufen, so oft Du willst.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Seyphedias schrieb:

    ja aber ich schreibe doch nicht
    Dann musst Du es sein lassen. X(
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ja läuft den deine Berechnung nicht in einer Schleife? Was berechnest du den?


    Es werden innerhalb des Threads mehrere Funktionen aufgerufen, innerhalb der einzelnen Funktion laufen unter anderem schleifen (zumindest bei iterativen sachen). Manchmal wird aber auch etwas rekursiv aufgerufen. Was der da im einzeln berechnet und optimiert möchte ich nicht sagen, aber es ist alles in allem sehr aufwendig. Alles was ich sagen kann ist, dass es sich um ein physikalisches Model handelt :)

    Seyphedias schrieb:

    sehr aufwendig
    Gruppiere die Funktionalität und sende nach dem Abarbeiten jeder Gruppe ein Progress-Event.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!