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.

    Ich habe den Fehler gefunden. Der Fehler entstand, wegen:

    VB.NET-Quellcode

    1. MsgBox("Einige Verzeichnisse konnten aufgrund ihrer Berechtigungen nicht gescannt werden!" & vbCrLf & errorlogg.Item(0), MsgBoxStyle.Critical, "Fehler")


    Was passiert aber, wenn es gar keinen Eintrag in errorrlogg gab? Eine Fehlermeldung. Ich habe das jetzt ein bisschen umgebaut:

    VB.NET-Quellcode

    1. If errorlogg.Count > 0 Then
    2. Dim message As String = ""
    3. For Each error1 In errorlogg
    4. message += vbCrLf & error1
    5. Next
    6. MsgBox("Einige Verzeichnisse konnten aufgrund ihrer Berechtigungen nicht gescannt werden!" + vbCrLf + message, MsgBoxStyle.Critical, "Fehler")
    7. End If
    8. errorlogg.Clear()


    Ich werde mich jetzt noch ein Mal an die Progressbar setzen.
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Ich hab mir nicht den ganzen Beitrag durchgelesen (weiß also nicht ob das schon erwähnt wurde), aber so weit ich weiß müssen alle Werte die am Ende des BGW öffentlich sein sollen im Result

    VB.NET-Quellcode

    1. ​e.Result
    stehen.

    VB.NET-Quellcode

    1. ​status.Text = "Vorgang abgeschlossen"
    2. Button1.Enabled = True
    3. MsgBox(listboxx1) 'Diese ist komischerweise KOMPLETT leer.


    Gruss

    ​mikeb69
    @mikeb69 Danke für die Antwort! Ich habe das Problem schon gelöst, er zeigt mir inzwischen alle Ergebnisse zuverlässig in der Liste an.

    @RodFromGermany Ich habe jetzt die Progressbar implementiert:

    VB.NET-Quellcode

    1. 'Im For Each Block:
    2. suche = suche + 1
    3. BGW.ReportProgress(CInt(suche / maxProgressBar * 100))
    4. Private Sub BGW_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
    5. Me.Fortschritt.Value = e.ProgressPercentage
    6. Me.Fortschritt.Update()
    7. End Sub


    Danke für die Hilfe!
    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:

    Ich habe das Problem schon gelöst, er zeigt mir inzwischen alle Ergebnisse zuverlässig in der Liste an.
    Glückwunsch!
    Nur viel interessanter finde ich, mit welcher Debug-Technik du dem Fehler auf die Schliche gekommen bist, und ob der eine oder annere Hinweis von hier da hilfreich war?

    ErfinderDesRades schrieb:

    Nur viel interessanter finde ich, mit welcher Debug-Technik du dem Fehler auf die Schliche gekommen bist, und ob der eine oder annere Hinweis von hier da hilfreich war?

    Ich hab das mit Breakpoints Stück für Stück durchgetestet. Auch habe ich mir einen extra Sub gemacht, um das ganze im Main Thread zu testen. Mein Vater hat mir dabei geholfen, das ganze richtig zu kompilieren und die Lösungsansätze von hier zu verwenden. Ich habe komischerweise einen mysteriösen Ordner in C:\Users\Michel\Documents\ namens Eigene Bilder. Er wird nicht gelistet, obwohl ich versteckte Dateien sehen kann. Er ist praktisch unsichtbar, super unsichtbar. Ich boote gleich meinen PC mal mit Ubuntu, um mir den Inhalt anzusehen.
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Also in Windows ist der von dir genannte Ordner Bestandteil des Betriebssystems - allerdings sollte er doch iwie sichtbar sein - evtl unter anderm Namen - etwa was bei mir im Datei-Explorer als Eigene Bilder-Ordner angezeigt ist, hat in Wirklich keit den Pfad:
    C:\Users\Account2\Pictures
    Windows hat da iwie einen Trick, dass manche Ordner eingedeutscht angezeigt werden, obwohl sie fürs Betriebssystem englisch bezeichnet sind.
    Vermutlich weisst du: Microsoft ist viel daran gelegen, das Betriebssystem so unübersichtlich und kryptisch zu gestalten als nur möglich - wo kämen wir hin, wenn die User verstünden, was da eiglich vor sich geht? ;)
    Langer Rede kurzer Sinn: Angugge i.O., aber ansonsten lass besser die Finger von diesem Ordner
    /Offtopic

    @Topic:
    Bist du noch an weiteren Verbesserungs-Vorschlägen interessiert?
    Dann poste halt den aktuellen Code - wir lassen uns dann was einfallen, dich zu beschäftigen ;)
    @ErfinderDesRades
    Mein aktueller Sourcecode:
    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 nowProgressBar As Integer = 0
    9. Dim maxProgressBar As Integer = 0
    10. Dim verzeichnis As String = "C:\"
    11. Dim WithEvents BGW As New System.ComponentModel.BackgroundWorker With {.WorkerReportsProgress = True, .WorkerSupportsCancellation = True}
    12. Dim CW As Integer = Me.Width ' Current Width
    13. Dim CH As Integer = Me.Height ' Current Height
    14. Dim IW As Integer = Me.Width ' Initial Width
    15. Dim IH As Integer = Me.Height ' Initial Height
    16. Private Sub Form1_Resize(ByVal sender As Object,
    17. ByVal e As System.EventArgs) Handles Me.Resize
    18. Dim RW As Double = (Me.Width - CW) / CW
    19. Dim RH As Double = (Me.Height - CH) / CH
    20. For Each Ctrl As Control In Controls
    21. Ctrl.Width += CInt(Ctrl.Width * RW)
    22. Ctrl.Height += CInt(Ctrl.Height * RH)
    23. Ctrl.Left += CInt(Ctrl.Left * RW)
    24. Ctrl.Top += CInt(Ctrl.Top * RH)
    25. Next
    26. CW = Me.Width
    27. CH = Me.Height
    28. End Sub
    29. Private Sub suchen_Click(sender As Object, e As EventArgs) Handles suchen.Click
    30. If Not BGW.IsBusy Then
    31. status.Text = "Bitte warten..."
    32. cancel.Enabled = True
    33. suchen.Enabled = False
    34. ' ausfuhren()
    35. BGW.RunWorkerAsync()
    36. PBLoading.Visible = True
    37. elapsed = 0
    38. Timer2.Start()
    39. End If
    40. End Sub
    41. Private Sub setdirectory_Click(sender As Object, e As EventArgs) Handles setdirectory.Click
    42. FolderBrowserDialog1.ShowDialog()
    43. verzeichnis = FolderBrowserDialog1.SelectedPath
    44. pfadBox.Text = verzeichnis
    45. End Sub
    46. Private Sub clearlist_Click(sender As Object, e As EventArgs) Handles clearlist.Click
    47. 'Momentan arbeite ich mit keiner Listbox, da ich gerade auf DataGridView umstelle!
    48. ListBox1.Items.Clear()
    49. End Sub
    50. Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
    51. Dim di As New DirectoryInfo(verzeichnis)
    52. Dim fiArr As FileInfo()
    53. Dim fri As FileInfo
    54. Dim MySize As Long
    55. Dim fiArrDetail As DirectoryInfo()
    56. Dim friDetail As DirectoryInfo
    57. Dim byti As Long = 1000000
    58. Try
    59. fiArr = di.GetFiles(("*"), SearchOption.AllDirectories)
    60. maxProgressBar = CInt(fiArr.Length)
    61. Catch ex As Exception
    62. 'Alle Directories
    63. fiArrDetail = di.GetDirectories()
    64. For Each friDetail In fiArrDetail
    65. Try
    66. di = New DirectoryInfo(friDetail.FullName)
    67. fiArr = di.GetFiles(("*"), SearchOption.AllDirectories)
    68. maxProgressBar += CInt(fiArr.Length)
    69. For Each fri In fiArr
    70. suche = suche + 1
    71. BGW.ReportProgress(CInt(suche / maxProgressBar * 100))
    72. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    73. If MySize >= NUD.Value * byti Then
    74. Dim grosse As Long = CLng(Math.Round(MySize / 1000000, 0))
    75. listboxx1.Add(fri.DirectoryName & "\" & fri.Name & " (" & grosse & " MB)")
    76. End If
    77. Next fri
    78. Catch ex1 As Exception
    79. errorlogg.Add(ex.Message)
    80. End Try
    81. Next friDetail
    82. 'Alle Files der obersten Ebene
    83. Try
    84. fiArr = di.GetFiles(("*"), SearchOption.TopDirectoryOnly)
    85. Catch ex2 As Exception
    86. End Try
    87. End Try
    88. For Each fri In fiArr
    89. MySize = FileLen(fri.DirectoryName & "\" & fri.Name)
    90. If MySize >= NUD.Value * byti Then
    91. Dim grosse As Long = CLng(Math.Round(MySize / 1000000, 0))
    92. listboxx1.Add(fri.DirectoryName & "\" & fri.Name & " (" & grosse & " MB)")
    93. suche = suche + 1
    94. BGW.ReportProgress(CInt(suche / maxProgressBar * 100))
    95. End If
    96. Next fri
    97. End Sub
    98. Private Sub BGW_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
    99. Fortschritt.Maximum = maxProgressBar
    100. If e.ProgressPercentage < maxProgressBar Then
    101. Me.Fortschritt.Value = e.ProgressPercentage
    102. Me.Fortschritt.Update()
    103. End If
    104. End Sub
    105. Private Sub BGW_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
    106. status.Text = "Vorgang abgeschlossen"
    107. suchen.Enabled = True
    108. Me.Fortschritt.Value = Fortschritt.Maximum
    109. For Each lb In listboxx1
    110. ListBox1.Items.Add(lb)
    111. Next
    112. Timer1.Enabled = True
    113. suche1.Text = CType(suche, String)
    114. listboxx1.Clear()
    115. suche1.Text = CType(suche, String)
    116. PBLoading.Visible = False
    117. Timer2.Stop()
    118. ps.Text = Math.Round(suche / elapsed, 0) & " pro Sekunde"
    119. suche = 0
    120. If errorlogg.Count > 0 Then
    121. Dim message As String = ""
    122. For Each error1 In errorlogg
    123. message += vbCrLf & error1
    124. Next
    125. MsgBox("Einige Verzeichnisse konnten aufgrund ihrer Berechtigungen nicht gescannt werden!" + vbCrLf + message, MsgBoxStyle.Critical, "Fehler")
    126. End If
    127. errorlogg.Clear()
    128. cancel.Enabled = False
    129. End Sub
    130. Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
    131. Timer1.Enabled = False
    132. status.Text = "Warte auf Input"
    133. Fortschritt.Value = 0
    134. End Sub
    135. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    136. PBLoading.Visible = False
    137. IW = Me.Width
    138. IH = Me.Height
    139. End Sub
    140. Private Sub Button4_Click(sender As Object, e As EventArgs) Handles exportlist.Click
    141. 'Momentan arbeite ich mit keiner Listbox, da ich gerade auf DataGridView umstelle!
    142. For Each flie In ListBox1.Items
    143. My.Computer.FileSystem.WriteAllText(Application.StartupPath() & "\BigFileFinder.txt", CType(flie, String) & vbCrLf, True)
    144. Next
    145. MessageBox.Show("Die Liste wurde in dem Ordner der Applikation abgespeichert!", "Gespeichert!", MessageBoxButtons.OK, MessageBoxIcon.Information)
    146. End Sub
    147. Private Sub clearexport_Click(sender As Object, e As EventArgs) Handles clearexport.Click
    148. Try
    149. My.Computer.FileSystem.DeleteFile(Application.StartupPath() & "\BigFileFinder.txt")
    150. MessageBox.Show("Die Liste wurde geleert und gelöscht!", "Gelöscht!", MessageBoxButtons.OK, MessageBoxIcon.Information)
    151. Catch ex As Exception
    152. End Try
    153. End Sub
    154. Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
    155. elapsed = elapsed + 0.1
    156. suche1.Text = CType(suche, String)
    157. End Sub
    158. Private Sub cancel_Click(sender As Object, e As EventArgs) Handles cancel.Click
    159. BGW.CancelAsync()
    160. End Sub
    161. End Class

    Designer:

    Und meine Controls:


    Ist ja mehr schon zum Lernprojekt geworden, finde ich aber gut :D

    Ich arbeite erstmal doch wieder mit einer Listbox.
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Jo, da kann man nu an verschiedenen Baustellen ansetzen.
    Ich greife mal das Thema "Layout" heraus.
    Also was du da im Form-Resize treibst, und mit die ganzen Variablen, die da rumfahren - das kann alles weg, wenn du das Layout-System von WinForms verstehst und richtig einzusetzen gelernt hast.
    Guck dir dazu Layout in Windows.Forms an, insbesondere die Videos.

    Vlt erkennst du allmählich das Prinzip von VisualBasic und VisualStudio: Nämlich dass für triviale Aufgaben grafische Programmier-Hilfen bereitstehen, sog. "Designer", mit denen man sich mit ein paar Klicks was zurecht-programmieren kann, was dann überaus stabil und gleichzeitig effizient ist, und dabei grosse Mengen an Code zu schreiben erübrigt.
    Eben das Visual.

    Diese Visual - Programmier-Techniken sind in Foren, Büchern, Tutorials oft schwer zu erklären, und daher wird vielerorts viel zu viel Code geschrieben - (manchmal gar tausende von Zeilen!), und viel Code - selbst wenn er total simpel ist - birgt immer die Gefahr, dass iwelche dumme Fehler sich drin verbergen.
    Daher sind grafische Programmiertechniken vorzuziehen, weil dem Designer-generiertem-Code unterläuft kein dummer Fehler.
    Und der User-Code wird dadurch gleichzeitig auf das wirklich Wesentliche reduziert - das ist ebenfalls ein unschätzbar wertvoller Vorteil, dass man nur noch das wirkliche Konzentrat an Logik zu programmieren hat, und von Trivial-Code befreit ist.
    Ich habe jetzt eine Groupbox gesetzt, ein bisschen am Layout mit dem Dock rumgespielt, das Video angeguckt und den Thread gelesen. Ich weiß jetzt, wie ich mehrere Tabellen mit Panels und Splittern etc. benutze, aber ich habe hier ja gar nicht so viel, was ich getrennt haben will. Es soll sich einfach nur vergrößern, wenn ich die Form vergrößere. Ich werde daraus irgendwie immer noch nicht schlau, wie ich jetzt dafür sorge, dass auch alles an seiner Stelle bleibt. Ich lege mal die Solution bei. @ErfinderDesRades
    Dateien
    • BigFileFinder.zip

      (416,53 kB, 200 mal heruntergeladen, zuletzt: )
    Die beste maschinelle Übersetzung der Welt - DeepL Übersetzer
    Alle Zitate, die ich seit dem 1.9.2017 übersetzt habe, wurden vollautomatisch mit DeepL übersetzt.



    Du hast ja immer noch nicht die Visual Studio - Empfohlene Einstellungen umgesetzt - wieso nicht?

    Nur Option Strict On über jede Datei zu schreiben ist ziemlich unzureichend - mach das doch ein für allemal klar, für dein ganzes Projekt, und für dein ganzes VisuaStudio überhaupt.
    Und schmeiss unbedingt auch den - ich nenne ihn: den "Deppen-Namespace" raus, weil annähernd alles, was der dir per Intellisense unter die Finger spielt, ist dummes Zeug, und behindert dich beim Einstieg in die objektorientierte Programmierung.

    Michdi schrieb:

    Ich werde daraus irgendwie immer noch nicht schlau, wie ich jetzt dafür sorge, dass auch alles an seiner Stelle bleibt.
    Naja, mit einem TableLayoutPanel, bei dem du genügend Zeilen und Spalten einrichtest - ist eiglich ziemlcih einfach.

    Edit: Also ich hab dir mal ein dynamisches Layout zusammengeklickst - mit einem - nein zwei TLPs.
    Ist noch nicht optimal, aber was wirklich optimal ist, musst ja eh du entscheiden.

    (Ach, und natürlich die Einstellungen habich korrigiert, und dann den Code minimal angepasst, dasses wieder läuft - bin ich ja gespannt, ob du die Unterschiede findest.)
    Dateien

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