Backgroundworker und die For Each Schleife

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

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von Michdi.

    Backgroundworker und die For Each Schleife

    Guten Abend Community!
    Da es mich ein bisschen genervt hat, dass sich mein Programm immer "aufhängt", sobald es etwas tut, wollte ich einen Backgroundworker benutzen. Ich war noch nie ein wirklicher Freund von diesem, da ich ihn nie richtig verstanden habe.
    Alles was ich möchte ist, dass er bestimmte Ergebnisse vergleicht und wenn eines zutrifft, dieses in einer Liste speichert und letztendlich in eine Listbox tut.
    Mein Code sieht wie folgt aus:

    VB.NET-Quellcode

    1. Dim suche As Integer = 0
    2. Dim listboxx1 As List(Of String)
    3. Dim errorlogg As List(Of String)
    4. Dim verzeichnis As String = "C:\Users\Michdi"
    5. Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    6. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    7. If Not BGW.IsBusy Then
    8. status.Text = "Bitte warten..."
    9. Button1.Enabled = False
    10. BGW.RunWorkerAsync()
    11. End If
    12. End Sub
    13. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
    14. Try
    15. suche = suche + 1
    16. Dim di As New DirectoryInfo(verzeichnis)
    17. Dim fiArr As FileInfo() = di.GetFiles("*", SearchOption.AllDirectories)
    18. Dim fri As FileInfo
    19. Dim MySize As Long
    20. Dim byti As Long = 1048576
    21. For Each fri In fiArr
    22. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    23. If MySize >= TextBox1.Text * byti Then
    24. Dim grosse As Long = Math.Round(MySize / 1048576, 0)
    25. listboxx1.Add(fri.DirectoryName & "\" & fri.Name & " (" & grosse & " MB)")
    26. End If
    27. Next fri
    28. Catch ex As Exception
    29. errorlogg.Add(ex.Message)
    30. End Try
    31. End Sub


    Und dann soll er die Dateien, die größer als x MB sind, in die ListBox1 tun:

    VB.NET-Quellcode

    1. Private Sub BGW_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
    2. Listbox1.Items.add(listboxx) 'Oder irgendwie anders
    3. End Sub
    4. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    5. status.Text = "Vorgang abgeschlossen"
    6. Button1.Enabled = True
    7. MsgBox(listboxx1) 'Diese ist komischerweise KOMPLETT leer.
    8. End Sub


    Am Ende sagt er mir sogar auch noch ganz stolz: Vorgang abgeschlossen :D
    Entweder bin ich zu dumm oder es ist einfach ein ganz dummer Fehler...
    Kann mir da jemand helfen?

    Danke! ?(

    *Topic verschoben*
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    @Michdi Also.
    Du arbeitest in einem Thread (der BGW ist einn Thread), um die GUI zu entlasten.
    Leider ist es von einem Thread aus nicht möglich, auf GUI-Komponenten zuzugreifen, da dies bei mehreen Threads parallel zu komplikationen kommen würde. Deshalb musst Du GUI-Zugriffe von einem Thread aus in den MainThread invoken. Bemühe bitte hierzu die Suchfunktion (Invoke), da gibt es gefühlte 1000 Treffer, von denen mehr als die Hälfte die Lösung ordentlich beschreiben.
    Das ProgressChanged-Event dient dazu, dem Hauptthread mitzuteilen, wieviel PROZENT der Arbeit getan sind. Damit kann dann die GUI z.B. eine Progressbar ansteuern.
    Zunächst sollte der Code als solcher im Main-Thread korrekt laufen. Teste das mit wenigen Dateien.
    Wenn er das nicht tut, hat es wenig Zweck, den Code in einen BGW zu verlagern, da das Debuggen in einem Thread sagen wir nicht gut funktioniert.
    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!
    Bei mir funktioniert Dein Code, wenn Du Option Strict On machst (-> Änderungen bearbeiten), der Hinweis von MichaHo befolgt wird, man Dim listboxx1 As New List(Of String) und Dim errorlog As New List(Of String) schreibt und bei BGW_RunWorkerCompleted eine For-Each-Schleife einbaut.

    VB.NET-Quellcode

    1. For Each lb In listboxx1
    2. MsgBox(lb) 'Diese ist komischerweise KOMPLETT leer. <- nicht bei mir. btw: besser MessageBox.Show verwenden
    3. Next

    Ach ja, die TextBox als Dateigrößeneinschränkungskriterium ist suboptimal -> NumericUpDown besser nehmen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    MichaHo schrieb:

    VB.NET-Quellcode

    1. Listbox1.Items.add(listboxx)

    sollte das nicht listboxx1 heissen?


    Ich habe das in meinem Code noch ein bisschen anders, habe es extra für hier ein bisschen umgeschrieben. Bei mir steht auch Listboxx1

    RodFromGermany schrieb:

    @Michdi Also.
    Leider ist es von einem Thread aus nicht möglich, auf GUI-Komponenten zuzugreifen... Deshalb musst Du GUI-Zugriffe von einem Thread aus in den MainThread invoken...
    Zunächst sollte der Code als solcher im Main-Thread korrekt laufen. Teste das mit wenigen Dateien.


    Das mit den GUI-Komponenten habe ich auch schon herausgefunden. Das mit dem Invoken werde ich mir mal angucken, danke! Der Code läuft im MainThread super, nur manchmal wirft er Fehlermeldungen bei zu großen Dateimengen, weil er auf manche Dateien keine Zugriffsberechtigungen hat, selbst als Admin. Danke trotzdem!

    VaporiZed schrieb:

    Bei mir funktioniert Dein Code, wenn Du Option Strict On machst...
    Ach ja, die TextBox als Dateigrößeneinschränkungskriterium ist suboptimal -> NumericUpDown besser nehmen.


    Danke, ich werde mal gucken, ob Option Strict bei mir auf On ist. Sollte sie eigentlich. Danke für die Idee mit NumericUpDown!


    EDIT:

    @VaporiZed Danke vielmals! Jetzt klappt alles! :D

    Mein Lösungsansatz:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Dim suche As Integer = 0
    4. Dim listboxx1 As New List(Of String)
    5. Dim errorlogg As New List(Of String)
    6. Dim verzeichnis As String = "C:\Users\Michel\Videos\GoPro"
    7. Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    8. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    9. If Not BGW.IsBusy Then
    10. status.Text = "Bitte warten..."
    11. Button1.Enabled = False
    12. BGW.RunWorkerAsync()
    13. End If
    14. End Sub
    15. Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    16. verzeichnis = TextBox2.Text
    17. End Sub
    18. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    19. ListBox1.Items.Clear()
    20. End Sub
    21. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
    22. Try
    23. Dim di As New DirectoryInfo(verzeichnis)
    24. Dim fiArr As FileInfo() = di.GetFiles("*", SearchOption.AllDirectories)
    25. Dim fri As FileInfo
    26. Dim MySize As Long
    27. Dim byti As Long = 1048576
    28. For Each fri In fiArr
    29. suche = suche + 1
    30. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    31. If MySize >= NUD.Value * byti Then
    32. Dim grosse As Long = Math.Round(MySize / 1048576, 0)
    33. listboxx1.Add(fri.DirectoryName & "\" & fri.Name & " (" & grosse & " MB)")
    34. End If
    35. Next fri
    36. Catch ex As Exception
    37. End Try
    38. End Sub
    39. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    40. status.Text = "Vorgang abgeschlossen"
    41. Button1.Enabled = True
    42. For Each lb In listboxx1
    43. ListBox1.Items.Add(lb)
    44. Next
    45. Timer1.Enabled = True
    46. suche1.Text = suche
    47. End Sub
    48. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    49. Timer1.Enabled = False
    50. status.Text = "Warte auf Input"
    51. End Sub
    52. End Class

    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Marcus Gräfe“ ()

    Erforsche mal den Inhalt der Klasse FileInfo.

    Michdi schrieb:

    VB.NET-Quellcode

    1. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    machst Du

    VB.NET-Quellcode

    1. MySize = fri.Length
    ,
    fri.DirectoryName & "\" & fri.Name machst Du fri.FullName
    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!

    Michdi schrieb:

    VB.NET-Quellcode

    1. If MySize >= TextBox1.Text * byti Then
    Was wäre in diesem Kontest "Roulade mit Klößen" MAL 5 :?: Eine satte Familie :?:
    Machst Du Option Strict On. Gugst Du hier.
    =====
    Probier mal dies:

    VB.NET-Quellcode

    1. Dim di As New DirectoryInfo(verzeichnis)
    2. Dim fiArr As FileInfo() = di.GetFiles("*.*", SearchOption.AllDirectories) ' *.*
    3. Dim MySize As Long
    4. Dim byti As Long = CInt(TextBox1.Text) * 1048576 ' besser wäre NumericUpDown
    5. For Each fri As FileInfo In fiArr
    6. MySize = fri.Length ' das hat FileInfo von zu Hause
    7. If MySize >= byti Then
    8. Dim grosse As Long = MySize \ 1048576 ' "\" ist Integer-Division
    9. Me.Invoke(Sub() listboxx1.Add(String.Format("{0} ({1} MB)", fri.FullName, grosse))) ' dies hier
    10. End If
    11. Next


    Verschoben aus Multithreading mit BackgroundWorker. (Da war ein Post des TEs, bevor er diesen Thread gestartet hat.) ~Thunderbolt
    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!

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

    Michdi schrieb:

    Danke vielmals! Jetzt klappt alles!
    Dassis schoma gut - da hat man quasi "ein Bein auf der Erde" :thumbup:

    Allerdings ist der Code in vielfacher Hinsicht noch stark verbesserungsfähig - das fängt mitte Benamung an, aber betrifft auch Sicherheit und logischen Ablauf.

    Nu Frage: Bist du interessiert an den vielen Verbesserungsvorschlägen, die da anstehen? Könntest u.U. eine grosse Menge draus lernen - bis hin zu den modernen Threading-Konzepten (Backgroundworker ist wirklich eine greuliche Gurke).

    Aber ich würde empfehlen, mit kleineren Änderungen anzufangen, die ausserdem grundlegender wichtig sind, also Benamung, Logik, Sicherheit.

    Wie gesagt, nur wenns dich interessiert...
    @ErfinderDesRades
    An Vorschlägen bin ich allgemein immer sehr interessiert, solange diese konstruktiv sind und nicht einfach beleidigend. Mit den Namen von den controls habe ich hier sehr viel gelernt, ich benenne inzwischen auch fast alle controls um, wenn ich größere Programme schreibe.
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Wunnebar!

    Also das erste und wichtigste ist, was Rod schon sagte: Visual Studio - Empfohlene Einstellungen
    Das erstmal abarbeiten - hinterher sieht dein Code schon bisserl anders aus (vorerst nicht schöner, aber mit leichter sichtbaren "Problem-Stellen")
    Also machma bitte, und poste dann den neuen Code.

    (Sorry, dassich jetzt doch mit einer größeren Änderung anfangen muss - dass Strict Off ist, hatte ich nicht mehr parat)

    Michdi schrieb:

    solange diese konstruktiv sind und nicht einfach beleidigend.
    Kann ich nicht nachvollziehen.
    Andersherum:

    Michdi schrieb:

    Jetzt klappt alles!
    zeugt von der Arroganz junger Programmierer-werden-woller, die der Meinung sind, dass jeder Code, der per C&P da reingepackt aber nicht verstanden und schon gar nicht getestet wird, läuft.
    ====
    Lies, verstehe, beherzige und lebe Zeile 2 meiner Signatur.
    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!
    Nanu? Hat doch niemand gesagt, dass hier im Thread konkret was beleidigendes gesagt wurde?
    Ich find hier auch nix kränkendes.
    Aber vorsorglich kann ich malwieder meine Empfehlung für ein dickes Fell empfehlen.
    Also jeden Post immer maximal wohlwollend zu lesen versuchen. Sich beleidigt fühlen bringt inhaltlich eiglich niemals was. Das hindert einen nur an der Aufnahme wichtiger und nützlicher Hinweise - und auch in "gefühlt beleidigenden" Posts sind ja sehr häufig richtige Hinweise enthalten - nach diesen sollte man suchen, und sie sich keinesfalls entgehen lassen.

    (Ich selbst hab zB. innem anneren Forum gradezu einen Spezi, mit dem gerate ich immer wieder ordentlich in Gezänk (Er hasst Datasets). Ich muss aber sagen, er hat mir einen Zugang zur T4-Template-Technologie geöffnet (falls jmd. weiss was das ist).)
    @ErfinderDesRades
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Imports System.IO
    3. Public Class Form1
    4. Dim suche As Integer = 0
    5. Dim listboxx1 As New List(Of String)
    6. Dim errorlogg As New List(Of String)
    7. Dim elapsed As Double = 0
    8. Dim verzeichnis As String = "C:\"
    9. Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    10. Private Sub suchen_Click(sender As Object, e As EventArgs) Handles suchen.Click
    11. If Not BGW.IsBusy Then
    12. status.Text = "Bitte warten..."
    13. suchen.Enabled = False
    14. BGW.RunWorkerAsync()
    15. PBLoading.Visible = True
    16. elapsed = 0
    17. Timer2.Start()
    18. End If
    19. End Sub
    20. Private Sub setdirectory_Click(sender As Object, e As EventArgs) Handles setdirectory.Click
    21. FolderBrowserDialog1.ShowDialog()
    22. verzeichnis = FolderBrowserDialog1.SelectedPath
    23. pfadBox.Text = verzeichnis
    24. End Sub
    25. Private Sub clearlist_Click(sender As Object, e As EventArgs) Handles clearlist.Click
    26. 'Momentan arbeite ich mit keiner Listbox, da ich gerade auf DataGridView umstelle!
    27. 'ListBox1.Items.Clear()
    28. End Sub
    29. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
    30. Dim di As New DirectoryInfo(verzeichnis)
    31. Dim fiArr As FileInfo()
    32. Dim fri As FileInfo
    33. Dim MySize As Long
    34. Dim fiArrDetail As DirectoryInfo()
    35. Dim friDetail As DirectoryInfo
    36. Dim byti As Long = 1000000
    37. Try
    38. fiArr = di.GetFiles(("*"), SearchOption.AllDirectories)
    39. Catch ex As Exception
    40. 'Alle Directories
    41. fiArrDetail = di.GetDirectories()
    42. For Each friDetail In fiArrDetail
    43. Try
    44. di = New DirectoryInfo(friDetail.FullName)
    45. fiArr = di.GetFiles(("*"), SearchOption.AllDirectories)
    46. For Each fri In fiArr
    47. suche = suche + 1
    48. BGW.ReportProgress(suche)
    49. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    50. If MySize >= NUD.Value * byti Then
    51. Dim grosse As Long = CLng(Math.Round(MySize / 1000000, 0))
    52. listboxx1.Add(fri.DirectoryName & "\" & fri.Name & " (" & grosse & " MB)")
    53. End If
    54. Next fri
    55. Catch ex1 As Exception
    56. errorlogg.Add(ex.Message)
    57. End Try
    58. Next friDetail
    59. 'Alle Files der obersten Ebene
    60. Try
    61. fiArr = di.GetFiles(("*"), SearchOption.TopDirectoryOnly)
    62. Catch ex2 As Exception
    63. End Try
    64. End Try
    65. For Each fri In fiArr
    66. suche = suche + 1
    67. BGW.ReportProgress(suche)
    68. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    69. If MySize >= NUD.Value * byti Then
    70. Dim grosse As Long = CLng(Math.Round(MySize / 1000000, 0))
    71. listboxx1.Add(fri.DirectoryName & "\" & fri.Name & " (" & grosse & " MB)")
    72. End If
    73. Next fri
    74. End Sub
    75. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    76. status.Text = "Vorgang abgeschlossen"
    77. suchen.Enabled = True
    78. For Each lb In listboxx1
    79. DataGridView.Rows.Add("Hallo")
    80. Next
    81. Timer1.Enabled = True
    82. suche1.Text = CType(suche, String)
    83. listboxx1.Clear()
    84. suche1.Text = CType(suche, String)
    85. PBLoading.Visible = False
    86. Timer2.Stop()
    87. ps.Text = Math.Round(suche / elapsed, 0) & " pro Sekunde"
    88. suche = 0
    89. MsgBox("Einige Verzeichnisse konnten aufgrund ihrer Berechtigungen nicht gescannt werden!" & vbCrLf & errorlogg.Item(1), MsgBoxStyle.Critical, "Fehler")
    90. errorlogg.Clear()
    91. End Sub
    92. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    93. Timer1.Enabled = False
    94. status.Text = "Warte auf Input"
    95. End Sub
    96. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    97. PBLoading.Visible = False
    98. End Sub
    99. Private Sub Button4_Click(sender As Object, e As EventArgs) Handles exportlist.Click
    100. 'Momentan arbeite ich mit keiner Listbox, da ich gerade auf DataGridView umstelle!
    101. 'For Each flie In ListBox1.Items
    102. 'My.Computer.FileSystem.WriteAllText(Application.StartupPath() & "\BigFileFinder.txt", flie & vbCrLf, True)
    103. ' Next
    104. MessageBox.Show("Die Liste wurde in dem Ordner der Applikation abgespeichert!", "Gespeichert!", MessageBoxButtons.OK, MessageBoxIcon.Information)
    105. End Sub
    106. Private Sub clearexport_Click(sender As Object, e As EventArgs) Handles clearexport.Click
    107. Try
    108. My.Computer.FileSystem.DeleteFile(Application.StartupPath() & "\BigFileFinder.txt")
    109. MessageBox.Show("Die Liste wurde geleert und gelöscht!", "Gelöscht!", MessageBoxButtons.OK, MessageBoxIcon.Information)
    110. Catch ex As Exception
    111. End Try
    112. End Sub
    113. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    114. elapsed = elapsed + 0.1
    115. suche1.Text = CType(suche, String)
    116. End Sub
    117. End Class


    Das ist jetzt mein kompletter Code. Dieses geschachtelte Zeug beim BGW ist noch nicht ganz aufgeräumt, erfüllt aber erstmal den Zweck: Weitermachen, wenn er auf ein Verzeichnis keinen Zugriff hat.

    @RodFromGermany
    Wieso kannst du das nicht nachvollziehen?
    Ich hatte vorher eigentlich in meinen Einstellungen Option Strict auf Off. Wieso er trotzdem gearbeitet hat, als ob Option Strict auf On war, weiß ich nicht.
    Mit konstruktiv ist eine förderliche, positive Haltung einnehmende Antwort gemeint. Wenn dem nicht so wäre, würde ja jeder hier verzweifeln, der nur eine Frage stellt.
    Ich kann ja verstehen, dass manche Fragen, auch von mir, echt dumm klingen, aber trotzdem freue ich mich eher auf die Antworten im Forum hier, die nicht eine Diskriminierung implizieren.
    Ich habe durchaus mein Programm mit dem Debugger eine ganze Weile, auch den neuen Code, getestet. Ich meine nicht, dass in diesem Post jetzt Beleidigungen vorhanden sind, eventuell sogar nicht ein Mal in diesem Forum, aber ich weiß, wie viele Menschen im Internet andere Leute beleidigen, ohne die Person zu kennen. Ich fühle mich davon nicht beleidigt, stört mich eigentlich auch nicht. Mit der Antwort "Jetzt klappt alles!" war nur gemeint, dass der Erst-Test funktioniert. Ich finde nicht, dass das von der Arroganz junger Programmierer-werden-woller zeugt. Ich habe von hier eigentlich auch nur den Block For Each lb in listboxx1.list genommen.

    Ich könnte da noch ewig weiterschreiben, aber ich weiß nicht wofür, wenn weder du, noch ich damit ein Problem haben. Meinungsdifferenzen gibt es immer, es ist ja auch nicht schlimm, diese zu besprechen, solange es nicht eskaliert.
    Zusammengefasst: Ich kann deinen Standpunkt schon verstehen.
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    @Michdi Du lässt einen BGW die Arbewit machen und testest mit einem Timer, wie weit der ist?
    Wenn Du weist, wie weit der ist, sende ein ReportProgress(PROZENT). Teste mal dies:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    3. ' dies kann auch im Designer gemacht werden
    4. Me.BackgroundWorker1.WorkerReportsProgress = True
    5. End Sub
    6. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    7. Me.BackgroundWorker1.RunWorkerAsync()
    8. End Sub
    9. Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    10. For i As Integer = 1 To 100
    11. ' kleine Pause
    12. System.Threading.Thread.Sleep(20)
    13. ' Event senden
    14. Me.BackgroundWorker1.ReportProgress(i)
    15. Next
    16. End Sub
    17. Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    18. ' Event behandeln
    19. Me.ProgressBar1.Value = e.ProgressPercentage
    20. Me.ProgressBar1.Update()
    21. End Sub
    22. Private Sub BackgroundWorker1_RunWorkerCompleted(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    23. MessageBox.Show("feddich")
    24. End Sub
    25. 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!
    @RodFromGermany
    Ich weiß leider am Anfang noch nicht, wie viele Dateien er durchsuchen wird. Um trotzdem eine minimale Anzeige zu haben, wie weit er ist und ob er noch arbeitet, habe ich einen Timer auf 1000 Millisekunden gestellt und jedes mal wenn dieser anschlägt das Label [tt]suche1[\tt] zum update gebracht. Das Label wird nicht direkt durch den BackgroundWorker_ProgressChanged Block gemacht, da der Computer meist tausende Dateien in einer Sekunde scannt und so das grafisches Interface praktisch aufhängt und damit den BGW unnötigt macht.
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Michdi schrieb:

    VB.NET-Quellcode

    1. For Each fri In fiArr
    2. suche = suche + 1
    3. BGW.ReportProgress(suche)
    Für jede Datei sendest Du ein Event.
    Die Dauer der Abarbeitung für jede Datei ist gleich lang.
    Das Array fiArr hat eine wohl definierte Länge.
    Also:
    Teile die Länge durch 100, verwende einen (Mit-)Zähler bis zu dieser Zahl, sende ein Event, wenn der (Mit-)Zähler gleich dieser Zahl ist,
    inkrementiere im Eventhandler eine ProgressBar und feddich.
    Und
    Aboniere das .ProgressChanged-Event, das vermisse ich nämlich in Deinem Code. ;)
    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!
    @RodFromGermany
    Ich habe jetzt für beide For Each Schleifen

    VB.NET-Quellcode

    1. Dim maxProgressBar As Integer = CInt(fiArr.Length / 100)
    2. Fortschritt.Maximum = maxProgressBar
    3. For Each fri in fiArr
    4. suche = suche +1
    5. BGW.ReportProgress(suche)
    6. Next fiarr
    7. Private Sub BGW_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
    8. Me.Fortschritt.Value = e.ProgressPercentage
    9. Me.Fortschritt.Update()
    10. End Sub


    Ich kann das aber leider nicht debuggen, da er jedes Mal eine System.Reflection.TargetInvocationException in mscorlib.dll wirft. Leider kenne ich diesen Fehler nicht, Google half nicht viel und er zeigt mir die Fehlermeldung in einem neuen Tab namens Source not Available



    Quellcode

    1. System.Reflection.TargetInvocationException occurred
    2. Message: Exception thrown: 'System.Reflection.TargetInvocationException' in mscorlib.dll
    3. Additional information: Exception has been thrown by the target of an invocation.

    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



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

    Michdi schrieb:

    Leider kenne ich diesen Fehler nicht
    Das heißt, dass die Exception in einem anderen Thread geworden wurde und / oder dass er in einer DLL vom FrameWork generiert wurde.
    Um hier einen laufenden Code zu generieren empfehle ich Dir, dies im Main Thread zu machen, z.B. in einer Button_Click. Der blockiertr zwar die GUI, aber er läuft im Main Thread und kann einfach debuggt werden.
    Teste dies mit einigen wenigen Dateien, und wenn der Code läuft, packst Du ihn in einen BGW.
    =====
    Ich denke mal, dass Du einen zu hohen Wert für Percentage gesendet hast, fange dies im ProgressChanged-Event ab und überlege dann, woher der Fehler kommt.
    =====
    Du kannst da auch ZU TESTZWECKEN ein Try / Catch drumherum bauen und Dir dann die Fehlermeldung genau ansehen.
    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!

    RodFromGermany schrieb:

    Du kannst da auch ZU TESTZWECKEN ein Try / Catch drumherum bauen und Dir dann die Fehlermeldung genau ansehen.
    Das würd ich favorisieren, weil ich hab schon eine Vermutung, was dabei herauskommt.
    Aber ich find debuggen lernen immer wichtiger, als Lösungen präsentieren, daher mach den TryCatch um den kompletten nebenläufigen Teil, und setze im Catch - Abschnitt einen Haltepunkt, wo du dann die Exception untersuchen kannst.

    Oder noch besser:
    Mach im RunworkerCompleted folgendes:

    VB.NET-Quellcode

    1. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    2. Dim X = e.Exception
    3. '...
    Da kannste dann auch mit Haltepunkt die Exception untersuchen.
    Hoffe ich jdfs - du weißt ja: Ich benutze diese Gurke eiglich garnet.

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