Algorithmusausführungs Problem

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von raist10.

    Algorithmusausführungs Problem

    Hallooo,

    habe einen Algorithmus mit dem ich rekursiv durch alle Unterordner eines Verzeichnis laufe.

    Wenn ich z. B. lokal den Programmeordner durchlaufe, treten keine Probleme auf.

    Wenn ich ein größeres Verzeichnis lokal oder nicht durchlaufe, reagiert das Programm alle paar Sekunden kurz nicht und läuft anschließend weiter.



    Woran könnte das liegen? Vermute das der Algorithmus zu schnell ist und die Festplatte kurzfristig überfordert ist, also sich nicht schneller drehen kann.
    Lagere den Durchsuchvorgang in einen extra Thread aus, dann sollte das Problem nicht mehr kommen.

    Denn wenn solche aufwendingen bzw. Zeitaufwendingen Dinge im gleichen Thread wie das Hauptprogramm ausgeführt werden, kann es zu solchen Problemen kommen.
    lg.

    LucaWelker
    Kannst Du Deinen Algorithmus bitte mal als Code hierher posten?
    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!
    Wie sieht der Algorythmus denn aus? Eigentlich sollte das Auslesen der Unterordner eines Verzeichnisses mit der richtigen Methode keine Zeitverzögerung beim Zugriff verursachen da diese Informationen rein aus der FAT ausgelesen werden.

    Z.B. so (Grobprinzip, bitte so natürlich nicht umsetzen):

    VB.NET-Quellcode

    1. For Each Folder As String In System.IO.Directory.GetDirectories("C:\")
    2. ' Debug.Print("Folder: " & Folder)
    3. For Each SubFolder As String In System.IO.Directory.GetDirectories(Folder)
    4. ' Debug.Print("SubFolder: " & SubFolder)
    5. For Each SubSubFolder As String In System.IO.Directory.GetDirectories(SubFolder)
    6. 'Debug.Print("SubSubFolder: " & SubFolder)
    7. Next SubSubFolder
    8. Next SubFolder
    9. Next Folder


    Wenn Du das debug.print rauslässt dauert der Durchlauf keine Sekunde selbst über die komplette Festplatte mit einigen 100 GB belegten Speicherplatz hinweg.
    Die Verarbeitung ist meistens das was Zeit in Anspruch nimmt. Hier könnte es sinnvoll sein entweder einen eigenen Thread dafür zu erstellen oder schlicht im old-fashioned-style mit System.Windows.Forms.Application.DoEvents() nach einer Verarbeitung der Prozessor kurz Luft zu verschaffen. ;)

    Gruß
    Rainer

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

    ubunet schrieb:

    reagiert das Programm alle paar Sekunden kurz nicht und läuft anschließend weiter.
    Um klarzustellen: Das Prog stockt einmal für ein paar Sekunden, nichtwahr?
    Wenns alle paar Sekunden stocken täte, hast du einen anderen, ziemlich ungewöhnlichen Fehler drinne.

    raist10 schrieb:

    Wenn Du das debug.print rauslässt dauert der Durchlauf keine Sekunde selbst über die komplette Festplatte mit einigen 100 GB belegten Speicherplatz hinweg.

    Ja, weil du nur Folder, SubFolder und SubSubFolder ausliest.

    Das Dateisystem ist aber wesentlich tiefer verschachtelt
    @raist10: Da hat glaub einer das Wort Rekursiv net verstanden, bzw. net drangedacht dass hier eine Rekursion notwendig ist um wie ErfinderDEsRades schon korrekt gesagt hat die volle tiefe des Dateisystems zu erfassen.

    Mit allen Dateien und Ordner machst du 100 GB niemals in ein Paar sekunden.

    lg.
    lg.

    LucaWelker
    Was hat denn der rekursive Aufruf der Folders mit der Größe der Festplatte zu tun? Es ist und bleibt ein Zugriff auf die FAT, reine Auslesung des Inhaltsverzeichnisses.

    Probiert es aus:

    VB.NET-Quellcode

    1. Private m_Counter As Integer = 0
    2. Public Function TestDirRekursiv() As String
    3. m_Counter = 0
    4. DirRekursiv("C:\")
    5. Return "Abgearbeitete Ordner: " & m_Counter
    6. End Function
    7. Public Sub DirRekursiv(ByVal strDir As String)
    8. Dim Folder As String = ""
    9. Try
    10. For Each Folder In System.IO.Directory.GetDirectories(strDir)
    11. m_Counter += 1
    12. If System.IO.Directory.GetDirectories(Folder).GetUpperBound(0) > 0 Then
    13. DirRekursiv(Folder)
    14. End If
    15. Next Folder
    16. Catch
    17. Debug.Print("Kein Zugriff mglich: " & Folder)
    18. End Try
    19. End Sub


    Arbeitet bei mir alle rd. 1000 Folder von C:\ bei 340 GB in unter 2 Sekunden ab. Und der TE hatte sich ja nur auf Folders und SubFolders bezogen und nicht auf Files. Mit Files dauert es ein wenig länger, allerdings nicht weil es mehr GB's sind sondern schlicht mehr Einträge in der FAT abzuarbeiten.

    Gruß

    Rainer

    EDITH: Ich hasse die Code-Einfüge-Funktion hier. ^^ Jemand einen Tipp wie ich ohne Nachkorrektur Code direkt aus dem VB.NET-Editor hier einfügen kann?

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

    raist10 schrieb:

    Jemand einen Tipp wie ich ohne Nachkorrektur Code direkt aus dem VB.NET-Editor hier einfügen kann?

    Ich benutze immer die "Quellcode"-TabPage des Forum-Post-Editors.

    Edit: Bei deim Code stand meine App für 2min stille.

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

    Habe jetzt mal spaßeshalber den obigen Code noch so ergänzt das in jedem Folder (und auch in jedem Subfolder) auch die einzelnen Files gezählt werden.

    Durchlauf für "C:\" mit 340 GB belegtem Volumen:

    Ergebnis: 996 Folders, 13876 Files

    Zeitbedarf: immer noch unter 2 Sekunden

    Durchlauf auf "O:\" (externe Festplatte mit USB 2.0-Anschluss) mit 620 GB belegtem Volumen:

    Ergebnis: 5980 Folder, 91242 Files

    Zeitbedarf: rd. 20 Sekunden

    Ich denke der Beweis ist deutlich das die Dauer alle Folder und Files auszulesen in keinster Weise abhängig von dem belegten Volumen ist sondern rein von der Anzahl der Einträge in der FAT und natürlich davon wie schnell die Verbindung zum Laufwerk ist. ;)

    EDITH:

    @ ErfinderDesRades

    Danke für den Tip ... will aber irgendwie nicht richtig bei mir funzen ... Du meinst doch das Button mit dem Sharp-Zeichen (#), richtig?

    Aber das Deine App für 2 Minuten still stand ist ja jetzt echt ein Gag. Hab das jetzt mal spaßeshalber (interessiert mich jetzt gerade selber) auch noch auf 2 anderen Rechnern durchlaufen lassen ... überall das gleiche bei Zugriff auf C (keiner weniger als 300 GB belegtes Volumen) unter 2 Sekunden und durch ... und beides Male war es sogar noch der Test-Code der auch gleich alle Files mit ausliest.

    Unterschiede in der NET-Version (arbeite mit 2008) oder dem Net-Framework (kann aber eigentlich nicht sein)? *verwirrt ist*

    EDIT von Tante EDITH: Hast Du das auf LW C probiert oder auf ein externes Laufwerk wie z.B. Netwerklaufwerk? Kannst Du mal noch einen Durchlauf probieren und nur vor dem rekursiven Aufruf innerhalb der Folder-Schleife ein kurzes DoEvents einbauen?


    Gruß

    Rainer

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „raist10“ ()

    VB.NET-Quellcode

    1. Public Class frmGetAllFolders
    2. Private Sub btGetAllFolders_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btGetAllFolders.Click
    3. Dim sw = Stopwatch.StartNew
    4. Me.Text = TestDirRekursiv() & ", milliseconds: " & sw.ElapsedMilliseconds
    5. End Sub
    6. Private m_Counter As Integer = 0
    7. Public Function TestDirRekursiv() As String
    8. m_Counter = 0
    9. DirRekursiv("C:\")
    10. Return "Abgearbeitete Ordner: " & m_Counter
    11. End Function
    12. Public Sub DirRekursiv(ByVal strDir As String)
    13. Dim Folder As String = ""
    14. Try
    15. For Each Folder In IO.Directory.GetDirectories(strDir)
    16. m_Counter += 1
    17. If IO.Directory.GetDirectories(Folder).GetUpperBound(0) > 0 Then
    18. DirRekursiv(Folder)
    19. End If
    20. Next Folder
    21. Catch
    22. Debug.Print("Kein Zugriff mglich: " & Folder)
    23. End Try
    24. End Sub
    25. End Class


    Tja - wunder mich auch - jetzt gehts in 2,5s.
    Vmtl. affenscharfe Zugriffs-Optimierung des Betriebsystems.
    Bilder
    • Shots15.Png

      35,74 kB, 866×376, 108 mal angesehen

    ErfinderDesRades schrieb:

    Tja - wunder mich auch - jetzt gehts in 2,5s.
    Vmtl. affenscharfe Zugriffs-Optimierung des Betriebsystems.

    Kann es sein das es Dein erster Debug-Vorgang nach der Einfügung des Codes war? Dann bestünde die Möglichkeit das er 2 Minuten gebraucht hat um die komplette App zu debuggen. :D

    Okay, dumme Vermutung ... aber mir fällt keine andere plausible Erklärung ein, ausser Du hattest einen fetten Hintergrundprozess laufen der den Zugriff auf die FAT blockiert hat.

    Naja ... man wundert sich immer wieder bei MS. ^^

    Gruß

    Rainer