Backgroundworker?

  • VB.NET

Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von singu.

    Backgroundworker?

    moin,
    wollte mal wissen wie ich einen Backgroundworker verwende.
    ich möchte nämlich Sachen von eimen ordner auf einen anderen kopieren und wenn ich das mit einer schleife mache ist das Programm ja total ausgelastet.

    lg.
    [VB 2008] Backgroundworker

    Hatten wir hier zu oft..

    Suchfunktion benutzen ist klarer Vorteil.

    //Edit: In diesem Breitrag gleich ganz unten stehen auch die anderen Themen die sich mit Backgroundworker (o.ä.) befassen.
    "Wenn jemand in einem Betrieb unverzichtbar ist, dann ist dieser Betrieb falsch organisiert." - Roberto Niederer

    Ein kleines BGW Tutorial

    Hallo,

    hier ein kleines BackGroundWorker Tutorial.

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Private WithEvents bgw As New BackgroundWorker
    4. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    5. 'so startet man den bgw
    6. bgw.RunWorkerAsync()
    7. 'evtl. kann man etwas mit übergeben
    8. bgw.RunWorkerAsync("Dem bgw etwas mitgeben")
    9. End Sub
    10. Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    11. 'prüft ob der bgw noch läuft und beendet diesen dann
    12. 'bedingung - siehe form_load
    13. If bgw.IsBusy Then
    14. bgw.CancelAsync()
    15. End If
    16. End Sub
    17. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    18. 'erlaubt zugriff auf die windows form
    19. bgw.WorkerReportsProgress = True
    20. 'erlaubt unterbrechung des bgw z.b. wenn das programm beendet wird
    21. bgw.WorkerSupportsCancellation = True
    22. End Sub
    23. #Region "BackGroundWorker Events"
    24. Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    25. 'hier steht alles drinn, was im bgw abgearbeitet werden soll.
    26. 'um etwas in der windows form (anderer prozess) ausgeben zu können muss das
    27. 'bgw_progesschanged event ausgelöst werden
    28. 'z.b. so
    29. bgw.ReportProgress(100) 'die 100 steht hier für einen prozentsatz
    30. 'oder
    31. bgw.ReportProgress(100, "Muss was Ausgeben.") 'im zweiten parameter kann ein objekt übergeben werden
    32. End Sub
    33. Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
    34. 'von hier aus, kann auf die windows forms zugegriffen werden
    35. 'aber auch nur von hier aus
    36. End Sub
    37. Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
    38. 'dieses event wird angesprungen, wenn alles was in bgw_dowork abgearbeitet wurde.
    39. End Sub
    40. #End Region
    41. End Class

    gruss

    mikeb69
    hallo,

    passend zum thema:

    ich nutze den bgw nun zum ersten mal. wenn ich nun meinen beispielcode benutze, kommt der fehler:
    Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement Label1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
    mein code:

    VB.NET-Quellcode

    1. Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    2. Dim p As Long
    3. For i As Integer = 0 To 100000000
    4. p += 1
    5. Next
    6. Label1.Text = p
    7. End Sub
    8. Private Sub bgw_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
    9. MsgBox("Ende")
    10. End Sub


    kann mir jmd erklären, wie man das nun machen muss? :D

    danke :)
    Für ein Mindestmaß an Rechtschreibung, Interpunktion und Majuskeln!
    .... Liess deine Fehlermeldung, dann das obige Tutorial nochmals...

    (Im DoWork Event kannst du nicht auf deine Form zugreifen. Nimm :

    Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
    'von hier aus, kann auf die windows forms zugegriffen werden
    'aber auch nur von hier aus
    End Sub

    Edit: war wohl jemand Schneller rellenhcS
    "I think Microsoft has abused the Windows brand so much that it has lost its cachet."
    Paul Thurrott
    aaah, danke. jetzt versteh ich:

    man muss

    VB.NET-Quellcode

    1. Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    2. Dim p As Long
    3. For i As Integer = 0 To 100000000
    4. p += 1
    5. Next
    6. bgw.ReportProgress(100, p) 'im zweiten parameter kann ein objekt übergeben werden
    7. End Sub
    8. Private Sub bgw_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgw.ProgressChanged
    9. Label1.Text = e.UserState.ToString
    10. End Sub

    nutzen.

    aber es folgt gleich die nächste frage :P
    wenn der thread läuft, und ich

    VB.NET-Quellcode

    1. Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    2. bgw.CancelAsync()
    3. End Sub

    nutze, sollte der thread doch eigentlich abgebrochen sein. aber dennoch wird bei mir das RunWorkerCompleted-event ausgelöst, genauso wie das ProgressChanged-event. woran könnte das liegen?...
    Danke
    Für ein Mindestmaß an Rechtschreibung, Interpunktion und Majuskeln!
    Hab zu dem Abbrechen auch nochmal eine Frage.

    Im Moment nutze ich folgenden Code:

    VB.NET-Quellcode

    1. Private Sub frm_Optimieren_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
    2. If bgw_Optimierung.IsBusy Then
    3. bgw_Optimierung.CancelAsync()
    4. End If
    5. End Sub
    6. Private Sub bgw_Optimierung_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw_Optimierung.DoWork
    7. If bgw_Optimierung.CancellationPending Then 'Wurde Abbrechen aufgerufen?
    8. e.Cancel = True 'Abbrechen
    9. Exit Sub
    10. Else
    11. Try
    12. 'Datenbank optimieren
    13. myConnection.Open() 'Connection öffnen
    14. myCommand = New SQLiteCommand("VACUUM Einträge; VACUUM Kategorien", myConnection) 'Command festlegen
    15. myCommand.ExecuteNonQuery() 'Command ausführen
    16. myConnection.Close() 'Connection schliesen
    17. Catch ex As Exception
    18. MessageBox.Show(ex.Message)
    19. End Try
    20. End If
    21. End Sub
    22. Private Sub bgw_Optimierung_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw_Optimierung.RunWorkerCompleted
    23. If (e.Error IsNot Nothing) Then 'Bei Fehler
    24. MessageBox.Show("Folgender Fehler ist aufgetreten: " & vbNewLine & e.Error.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
    25. ElseIf e.Cancelled Then 'Bei Abbruch
    26. MessageBox.Show("Der Vorgang wurde abgebrochen.", "Abbruch", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
    27. Else 'Bei Erfolg
    28. MessageBox.Show("Optimierung erfolgreich abgeschlossen", "Optimierung abgeschlossen", MessageBoxButtons.OK, MessageBoxIcon.Information)
    29. End If
    30. Me.Close()
    31. End Sub


    Das Problem:
    Beim Schliesen der Form wird zwar das .CancelAsync() aufgerufen, jedoch kommt immer noch die Meldung das die Optimierung erfolgreich war. Was mache ich da falsch?
    wintoolz.de
    • wintoolz.KeyLocker - Programm zum sicheren Verwalten von Passwörten
    • wintoolz.CodeGallery - Datenbank für Codebeispiele veschiedener Programmiersprachen
    • wintoolz.Haushaltsbuch - Dient zum Auflisten der Aktivitäten ihrer Bankkonten

    Benutze auch du Ecosia
    Hi T1g0r,
    das Problem ist, dass der Code welcher das e.Cancel auf True setzt wohl nie aufgerufen wird. Es wird ja gleich beim initialisieren des Do-Work Events geprüft ob der Nutzer auf Abbrechen geklickt hat und danach wird der Datenbankquery ausgeführt und zum schluß die Funktion beendet. Daher würde es wohl am meisten Sinn machen die Abfrage ob der Worker abgebrochen wurde ans Ende der Funktion zu verlagern. Das hat allerdings nur kosmetischen Nutzen, denn wirklich Abbrechen kannst du den Worker in diesem Fall nicht, da er erstmal den DB-Query synchron abarbeitet und dabei nicht nachschaut ob der Benutzer auf Abbrechen geklickt hat.

    Cheerio
    OK, das hab ich mir schon fast gedacht.
    Danke
    wintoolz.de
    • wintoolz.KeyLocker - Programm zum sicheren Verwalten von Passwörten
    • wintoolz.CodeGallery - Datenbank für Codebeispiele veschiedener Programmiersprachen
    • wintoolz.Haushaltsbuch - Dient zum Auflisten der Aktivitäten ihrer Bankkonten

    Benutze auch du Ecosia
    Ich hänge mich mal hier rein.
    Ich wollte mal die Sache mit dem Backgroundworker testen, aber nun stehe ich vor einem Problem. Im Backgroundworker soll eine Variable aus dem normalen Programmbereich verwendet werden. Allerdings ist diese leer, wenn ich sie im Backgroundworker aufrufe. Wie kann ich auf die Variable zugreifen, damit das nicht der Fall ist?
    Damit solltest du ganz normal arbeiten können. Das diese Variable leer ist, dürfte nicht am Backgroundworker liegen.
    wintoolz.de
    • wintoolz.KeyLocker - Programm zum sicheren Verwalten von Passwörten
    • wintoolz.CodeGallery - Datenbank für Codebeispiele veschiedener Programmiersprachen
    • wintoolz.Haushaltsbuch - Dient zum Auflisten der Aktivitäten ihrer Bankkonten

    Benutze auch du Ecosia
    Das habe ich bereits versucht, aber die Msgbox bleibt trotzdem leer.

    VB.NET-Quellcode

    1. Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    2. Msgbox(meineVariable)
    3. End Sub