Suchprozess dauert lange

  • VB.NET

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

    Suchprozess dauert lange

    Salut zusammen
    Ich durchsuche einen Pfad nach bestimmten Dateien. Das Resultat ist auch so wie gewünscht aber die Suche selber dauert lange (50sec). Kann man das beschleunigen?

    VB.NET-Quellcode

    1. Private Sub btnSearchStart_Click(sender As System.Object, e As System.EventArgs) Handles btnSearchStart.Click
    2. ListBox12.Items.Clear()
    3. Dim sFile As String
    4. Dim sPath As String
    5. ' Startverzeichnis
    6. sPath = txtSearchPath.Text
    7. ' ggf. abschließenden Backslash hinzufügen
    8. If Not sPath.EndsWith("\") Then sPath += "\"
    9. ' alle *-Dateien im Startverzeichnis einschl. Unterordner
    10. ' in einer ListBox anzeigen
    11. For Each sFile In My.Computer.FileSystem.GetFiles(sPath, FileIO.SearchOption.SearchAllSubDirectories, txtSearchAttributh.Text)
    12. ' Dateiname mit relativer Pfadangabe zum Startverzeichnis ausgeben
    13. ListBox12.Items.Add(sFile.Substring(sPath.Length))
    14. Next
    15. End Sub
    16. Private Sub btnSearchOpenSelect_Click(sender As System.Object, e As System.EventArgs) Handles btnSearchOpenSelect.Click
    17. System.Diagnostics.Process.Start(txtSearchPath.Text & "\" & ListBox12.SelectedItem.ToString)
    18. End Sub


    imo dauert das nur lange, wenn als InitialPfad eine komplette Festplatte oder sonstwas riesiges ausgewählt wird.
    Datei-Suchen sind numal lahm, und wenn 50000 gefunden werden, dauert das eben.

    vlt. kannst du auch was mit Listbox.Items.AddRange() optimieren - aber fraglich, ob das viel bringt.
    Hi
    Der Pfad ist ein Netzwerk. Es dauert auch recht lange wenn ich den Pfad "tiefer" angebe so das nicht soviel durchsucht werden muss.
    Eigentlich ist es nicht mal so schlimm das das so lange dauert. Viel ärgerlicher ist es das während des suchens die ganze Applikation nicht mehr reagiert.
    Ist der Suchprozess abgeschlossen reagiert sie wieder wie gewollt.

    mathysjp schrieb:

    VB.NET-Quellcode

    1. Listbox2.SuspendLayout ' EINFÜGEN!
    2. For Each sFile In My.Computer.FileSystem.GetFiles(sPath, FileIO.SearchOption.SearchAllSubDirectories, txtSearchAttributh.Text)
    3. ' Dateiname mit relativer Pfadangabe zum Startverzeichnis ausgeben
    4. ListBox12.Items.Add(sFile.Substring(sPath.Length))
    5. Next
    6. Listbox2.ResumeLayout ' AUCH EINFÜGEN!


    Zusätzlich die Suche in einen eigenen Thread auslagern, bzw asynchron arbeiten

    mathysjp schrieb:

    Wie mache ich das?

    Dein Ernst?

    So nebenbei, du versucht nicht etwa die Explorer-Suche mit GetFiles nachzubasteln?
    Hoffe ich zumindest ;)

    Liebe Grüße

    Edit by ErfinderDesRades: bitte konstruktiv antworten!
    /nicht getestet

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

    mathysjp schrieb:

    Wie mache ich das?
    Post #4 von @picoflop: lesen.
    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!

    VB.NET-Quellcode

    1. Imports AsyncCtpExtensions
    2. Imports System.Threading.Tasks
    3. Public Class Form1
    4. Private Async Sub btnSelectFolder_Click(sender As System.Object, e As System.EventArgs) Handles btnSelectFolder.Click
    5. Dim fbd As New FolderBrowserDialog
    6. If fbd.ShowDialog = Windows.Forms.DialogResult.OK Then
    7. If fbd.SelectedPath.Length > 0 Then
    8. Dim l = Await SearchPath(fbd.SelectedPath)
    9. If l IsNot Nothing Then
    10. ListBox1.SuspendLayout()
    11. ListBox1.Items.Clear()
    12. ListBox1.Items.AddRange(l.ToArray)
    13. ListBox1.ResumeLayout()
    14. End If
    15. End If
    16. End If
    17. End Sub
    18. Private Async Function SearchPath(path As String) As Task(Of IEnumerable(Of String))
    19. Try
    20. Return My.Computer.FileSystem.GetFiles(path, FileIO.SearchOption.SearchAllSubDirectories)
    21. Catch ex As AccessViolationException
    22. Return Nothing
    23. End Try
    24. End Function
    25. End Class


    = Async!
    (geht mit Async CTP für Net 4.0 oder mit Net 4.5 outofthebox)

    rotherford schrieb:

    Dein Ernst?
    So nebenbei, du versucht nicht etwa die Explorer-Suche mit GetFiles nachzubasteln?
    Hoffe ich zumindest


    Auf jeden Fall nicht bewusst.

    RodFromGermany schrieb:

    Post #4 von @picoflop: lesen.


    Wenn ich den oberen Codeausschnitt in den Backgroundworker packe kommt sofort nach aufruf von

    VB.NET-Quellcode

    1. BackgroundWorker5.RunWorkerAsync()

    Eine Fehlermeldung --> Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement....

    mathysjp schrieb:

    ich denke eher: System.Windows.Forms.ListBox.BeginUpdate/EndUpdate

    Habe ich probiert, bringt nichts oder auf jeden Fall nicht merkbar.

    mathysjp schrieb:

    Ungültiger threadübergreifender Vorgang

    Stichwörter dazu:

    -Invoke
    -GUI Thread

    Such ein wenig dazu.
    Im Forum od. Google gibt es tausende Exemplare dazu ;9
    [VB.NET] Thread-Problem (Ungültiger threadübergreifender Vorgang)

    Was in deinem Fall interessant wäre, Rekursion:
    [VB 2010] Rekursive Dateisuche mit anonymer Methode
    vbarchiv.net/tipps/tipp_1506-d…r-rekursiv-ermitteln.html

    Liebe Grüße
    /nicht getestet

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

    mathysjp schrieb:

    Eine Fehlermeldung --> Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement....

    Nikmm nicht DoWork, sondern das Completed Event

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Private WithEvents bgw As New BackgroundWorker
    4. Private Sub bgw_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork
    5. Dim f As List(Of String)
    6. Try
    7. f = My.Computer.FileSystem.GetFiles(e.Argument.ToString).ToList
    8. Catch ex As AccessViolationException
    9. ' gnampf
    10. End Try
    11. e.Result = f
    12. End Sub
    13. Private Sub bgw_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgw.RunWorkerCompleted
    14. ListBox1.Items.AddRange(DirectCast(e.Result, List(Of String)).ToArray)
    15. End Sub
    16. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    17. If Not bgw.IsBusy Then
    18. bgw.RunWorkerAsync("c:\foo\bar")
    19. End If
    20. End Sub
    21. End Class