рекурсивный поиск и замедление работы

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Leon144
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 92
Зарегистрирован: 13.12.2008 (Сб) 9:57

рекурсивный поиск и замедление работы

Сообщение Leon144 » 03.03.2013 (Вс) 19:31

Доброго всем времечка!!

Есть код ( Он не мой, нашел на одном из форумом, добавил поток. Без него программа зависала):

Основная форма:

Код: Выделить всё
Imports System.Threading
Public Class Form1
    Public trd As Thread

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        trd = New Thread(AddressOf ThreadTask)
        trd.IsBackground = True
        trd.Start()
    End Sub

    Private Sub ThreadTask()
        Try
            Dim rnd As New Random()
            Dim searcher As New FindFiles
            For i As Object = 0 To My.Computer.FileSystem.Drives.Count
                For Each s As String In searcher.FindAllFiles(My.Computer.FileSystem.Drives.Item(i).ToString, "*.*")
                   ListBox1.Items.Add(s)
                    Label1.Text = s
                    Label2.Text = Label2.Text + 1
                    Thread.Sleep(150)
                Next
            Next
            ListBox1.Items.Add("Done!")
                   Catch
        End Try
    End Sub
End Class


Класс:

Код: Выделить всё
Class FindFiles
    Public Function FindAllFiles(ByVal startPath As String, ByVal pattern As String) As List(Of String)
        Dim dir As System.IO.DirectoryInfo = My.Computer.FileSystem.GetDirectoryInfo(startPath)
        Return FindFile(dir, SimplePat2RegEx(pattern))
    End Function

    Private Function SimplePat2RegEx(ByVal pattern As String) As String
        Return pattern.Replace("*", "[a-zA-Z0-9]+").Replace("?", "[a-zA-Z0-9]{1,1}")
    End Function

    Private Function FindFile(ByVal dir As IO.DirectoryInfo, ByVal pattern As String) As List(Of String)
        Dim out As New List(Of String)
        Try
            For Each f As IO.FileInfo In dir.GetFiles
                If IsMatch(f.FullName, pattern) Then
                    out.Add(f.FullName)
                    Debug.Print(f.FullName)
                End If
            Next

            For Each d As IO.DirectoryInfo In dir.GetDirectories
                For Each o As String In FindFile(d, pattern)
                    out.Add(o)
                Next
            Next
        Catch ex As Exception

        End Try

        Return out
    End Function

    Private Function IsMatch(ByVal filename As String, ByVal pattern As String)
        Dim regex As New System.Text.RegularExpressions.Regex(pattern)
        Return regex.IsMatch(filename)
    End Function
End Class


Все работает но, после нажатия на кнопку поиск начинается не сразу а с задержкой 20 - 30 сек. Как заставить работать сей код сразу, без задержки?
Заранее благодарю за помощь.
Хотели как лучше, получилось как всегда.

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: рекурсивный поиск и замедление работы

Сообщение FireFenix » 03.03.2013 (Вс) 19:59

Очевидно, вначале выложить твоей проект и как ты замеряешь, что он начинает с задержкой, а не выполняется 20 сек?

более того
Код: Выделить всё
Thread.Sleep(150)

обрабатываем 10 файлов и получаем задержку в 1 секунду. Для передачи управления другому потоку нада использовать Thread.Yield
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Leon144
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 92
Зарегистрирован: 13.12.2008 (Сб) 9:57

Re: рекурсивный поиск и замедление работы

Сообщение Leon144 » 03.03.2013 (Вс) 20:11

FireFenix писал(а):Очевидно, вначале выложить твоей проект и как ты замеряешь, что он начинает с задержкой, а не выполняется 20 сек?

Создал проект, запустил, Нажал на кнопку. Ждем секунд 20 и счетчик побежал с результатами поиска.



FireFenix писал(а):
Код: Выделить всё
Thread.Sleep(150)

обрабатываем 10 файлов и получаем задержку в 1 секунду. Для передачи управления другому потоку нада использовать Thread.Yield


Сия строчка вставлена для наглядности, убираем, тот же результат. Просто в последствии поиск работает быстрее....
Хотели как лучше, получилось как всегда.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 03.03.2013 (Вс) 21:01

Потому что этот код кривой во всём, в чём только можно. И кроме своей неоптимальности, ещё и не работает, т. к. некорректно приводит шаблон к регулярному выражению.

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 03.03.2013 (Вс) 21:19

Вот относительно нормальный способ:
Код: Выделить всё
Imports System.IO
Imports System.Threading

Public Class Form1

Private Sub BtnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSearch.Click
  Dim Mask As String = TxtMask.Text

  Call (New Thread(Sub()
    BtnSearch.Invoke(Sub() BtnSearch.Enabled = False)

    For Each Root As String In Directory.GetLogicalDrives()
      Search(Root, Mask, Sub(Results As String()) LstResult.Invoke(Sub() LstResult.Items.AddRange(Results)))
    Next Root

    BtnSearch.Invoke(Sub() BtnSearch.Enabled = True)
  End Sub)).Start()
End Sub

Sub Search(ByVal Folder As String, ByVal Mask As String, ByVal Callback As Action(Of String()))
  Try
    Callback(Directory.GetFiles(Folder, Mask))
  Catch ex As Exception
  End Try

  Try
    For Each Folder In Directory.GetDirectories(Folder)
      Search(Folder, Mask, Callback)
    Next Folder
  Catch ex As Exception
  End Try
End Sub

Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
  End
End Sub

End Class

FireFenix
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1640
Зарегистрирован: 25.05.2007 (Пт) 10:24
Откуда: Mugen no Sora

Re: рекурсивный поиск и замедление работы

Сообщение FireFenix » 03.03.2013 (Вс) 22:16

Qwertiy писал(а):Вот относительно нормальный способ:
Код: Выделить всё
Private Sub BtnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSearch.Click
  Dim Mask As String = TxtMask.Text

  Call (New Thread(Sub()
    BtnSearch.Invoke(Sub() BtnSearch.Enabled = False)

    For Each Root As String In Directory.GetLogicalDrives()
      Search(Root, Mask, Sub(Results As String()) LstResult.Invoke(Sub() LstResult.Items.AddRange(Results)))
    Next Root

    BtnSearch.Invoke(Sub() BtnSearch.Enabled = True)
  End Sub)).Start()
End Sub


Хардкор и садомия с лямбда функциями... Даже я так сильно не упарываюсь Изображение
Птицей Гермеса меня называют, свои крылья пожирая... сам себя я укрощаю
私はヘルメスの鳥 私は自らの羽根を喰らい 飼い慣らされる

Qwertiy
Доктор VB наук
Доктор VB наук
 
Сообщения: 2753
Зарегистрирован: 26.06.2011 (Вс) 21:26

Сообщение Qwertiy » 03.03.2013 (Вс) 22:57

FireFenix писал(а):Хардкор и садомия с лямбда функциями... Даже я так сильно не упарываюсь Изображение

Зато компактно :D


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17

    TopList