Dynamische mehrere Backgroundworker erstellen und benutzen

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Ponch0.

    Dynamische mehrere Backgroundworker erstellen und benutzen

    Hallo,

    ich habe mich gerade mal ein wenig mit dem Backgroundworker befasst und soweit auch alles verstanden. Jetzt möchte ich aber mehrere Backgroundworker dynamisch erstellen lassen. Sprich das Programm weiss vor der Inbetriebnahme nicht wieviele Worker es mal benutzen wird. Genau da liegt mein Problem!
    Ich habe das Internet durchsucht und auch einen halben Lösungsansatz gefunden. Man solle die Backgroundworker einfach als Array deklarieren, somit könne man ja soviele erstellen lassen, wie man möchte. Soweit sogut. Da ist aber dann das Handler-Problem!

    Wie weise ich den BGWs die passenden Adhandler zu? Ich habs bereits versucht, aber irgendwie willes nicht klappen.
    AddHandler bgw(0).DoWork, AddressOf Test
    AddHandler bgw(0).ProgressChanged, AddressOf ProgressChanged


    Das nimmt der Compiler irgendwie nicht an..

    Ich glaub ich bin total auf dem Holzweg. Vielleicht ist dies auch ein wenig zu "Hoch" für mein derzeitiges Grundwissen.. aber versuchen kann man es ja mal :)

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public bgw() As System.ComponentModel.BackgroundWorker
    3. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    4. ReDim bgw(0)
    5. AddHandler bgw(0).DoWork, AddressOf Test
    6. AddHandler bgw(0).ProgressChanged, AddressOf ProgressChanged
    7. End Sub
    8. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    9. bgw(0).RunWorkerAsync()
    10. End Sub
    11. Private Sub ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs)
    12. ProgressBar1.Value = e.ProgressPercentage
    13. End Sub
    14. Private Sub Test(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
    15. Dim a, b, a1, b1 As Integer
    16. Dim strtemp As String = ""
    17. Dim progress As Double
    18. a = 100
    19. b = 200
    20. For a1 = 0 To a - 1 Step 1
    21. For b1 = 0 To b Step 1
    22. strtemp &= a
    23. Next
    24. progress = (a1 + 1) * 100 / (a)
    25. bgw(0).ReportProgress(progress)
    26. Next
    27. End Sub
    28. End Class

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

    ThuCommix schrieb:

    Nach Test muss noch das ComponentModel Event rein.



    Grüße

    Jo das war noch nen kleiner Fehler, der mir aber nur beim übertragen hier hin passiert ist.

    Das Hauptproblem ist, dass er beim starten dern Form immer "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt." ausgibt. Das versteh ich aber nicht!
    Das liegt hieran:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. ReDim bgw(0)
    3. AddHandler bgw(0).DoWork, AddressOf Test
    4. AddHandler bgw(0).ProgressChanged, AddressOf ProgressChanged
    5. End Sub


    Das kann weg: Public bgw() As System.ComponentModel.BackgroundWorker


    Also am ende so:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim bgw as new BackGroundWorker
    3. AddHandler bgw.DoWork, AddressOf Test
    4. AddHandler bgw.ProgressChanged, AddressOf ProgressChanged
    5. End Sub

    ThuCommix schrieb:

    Das liegt hieran:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. ReDim bgw(0)
    3. AddHandler bgw(0).DoWork, AddressOf Test
    4. AddHandler bgw(0).ProgressChanged, AddressOf ProgressChanged
    5. End Sub


    Das kann weg: Public bgw() As System.ComponentModel.BackgroundWorker


    Also am ende so:

    VB.NET-Quellcode

    1. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    2. Dim bgw as new BackGroundWorker
    3. AddHandler bgw.DoWork, AddressOf Test
    4. AddHandler bgw.ProgressChanged, AddressOf ProgressChanged
    5. End Sub


    Danke erstmal für deine schnellen Antworten. Sehr lieb von dir :love:

    Trozdem löst das leider nicht mein Problem. Wie ich einen normalen BGW erstelle und benutze habe ich aus mehreren Tutorials hier aus diesem Forum bereits gelernt und dies funktioniert auch einwandfrei.
    Was allerdings nicht funktioniert ist, dass ich mehrere BGW's erstellen will, die ich aber wie o.g. erst erstellen will, wenn das Programm bereits läuft. D.H. der Benutzer soll selber auswählen wieviele BGW's er gleichzeitig laufen lassen will!
    Dafür wollte ich ja den BGW als Array definieren, damit ich die BGWs in eine Schleife packen kann.

    ca. so:

    VB.NET-Quellcode

    1. Dim bgw(NumericBox.Value - 1) As BackgroundWorker
    2. For i As Integer = 0 To NumericBox.Value - 1 Step 1
    3. bgw(i).RunWorkerAsync()
    4. Next

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

    Es ist recht unsinnig, viele Bgws zu erstellen. Wenn du viele Threads laufen haben möchtest, erstelle halt viele Threads.

    Günstiger isses, viele asynchrone Methoden aufzurufen, weil die bedienen sich aussem Threadpool, und manche sind sogar noch besonders optimiert.

    Häufig täuscht man sich auch, wenn man denkt, mit Threads Performance steigern zu können. Wie ist das in deinem Fall gelagert - warum brauchst du viele Threads?

    Ponch0 schrieb:

    Dim bgw(NumericBox.Value - 1) As BackgroundWorker

    Damit erzeugst du ein Array, das X Backgroundworker aufnehmen kann. Und nach dem erstellen des Arrays ist logischerweise erstmal KEINER drin ;)

    Wenn schon dann:

    VB.NET-Quellcode

    1. Dim bgw(NumericBox.Value - 1) As BackgroundWorker
    2. For i As Integer = 0 To NumericBox.Value - 1 Step 1
    3. bgw(i)=New Backgroundworker
    4. bgw(i).RunWorkerAsync()
    5. Next


    Da du Anfänger bist, bist du wahrscheinlich durcheinander gekommen, weil ein Array von Integers gleich mit "0" (also einem integer) belegt ist. Das ist aber nur bei bestimmten Variablen der Fall - wenn es nämlich "Werttypen" sind (auch wenn in Net natürlich alles irgendwie "object" ist). Aber wenn du mit etwas arbeitest, was von "object" erbt (also schon mal jede Klasse), dann musst du dieses Object vor der Verwendung erst erzeugen. Ansonsten hast du nur nen "leeren Zeiger", der auf ein Object zeigen KANN ... es aber erstmal nicht tut.

    picoflop schrieb:

    Ponch0 schrieb:

    Dim bgw(NumericBox.Value - 1) As BackgroundWorker

    Damit erzeugst du ein Array, das X Backgroundworker aufnehmen kann. Und nach dem erstellen des Arrays ist logischerweise erstmal KEINER drin ;)

    Wenn schon dann:

    VB.NET-Quellcode

    1. Dim bgw(NumericBox.Value - 1) As BackgroundWorker
    2. For i As Integer = 0 To NumericBox.Value - 1 Step 1
    3. bgw(i)=New Backgroundworker
    4. bgw(i).RunWorkerAsync()
    5. Next


    Da du Anfänger bist, bist du wahrscheinlich durcheinander gekommen, weil ein Array von Integers gleich mit "0" (also einem integer) belegt ist. Das ist aber nur bei bestimmten Variablen der Fall - wenn es nämlich "Werttypen" sind (auch wenn in Net natürlich alles irgendwie "object" ist). Aber wenn du mit etwas arbeitest, was von "object" erbt (also schon mal jede Klasse), dann musst du dieses Object vor der Verwendung erst erzeugen. Ansonsten hast du nur nen "leeren Zeiger", der auf ein Object zeigen KANN ... es aber erstmal nicht tut.


    Danke schön Picoflop. Genau das war mein Fehler! Sehr nett erklärt und auch für mich als Laien verständlich! :thumbsup: :thumbsup: