VB .net BackgroundWorker

AlmaMater

Power Member
Hello,

Com o objectivo de obter todo o conteúdo de uma directoria tenho 2 SUBs recursivos o WorkWithDirectory e o WorkWithFilesInDir:

Código:
Private Sub ListaFicheiros()
        Dim nameOfDirectory As String
        CLB.Items.Clear() ' CheckListBox
            
         nameOfDirectory = Label1.Text 
      
        Dim myDirectory As DirectoryInfo
        myDirectory = New DirectoryInfo(nameOfDirectory)
        [COLOR="Blue"]WorkWithDirectory(myDirectory)[/COLOR]
    End Sub

    Private Sub WorkWithDirectory(ByVal aDir As DirectoryInfo)
         Dim nextDir As DirectoryInfo
        [COLOR="blue"]WorkWithFilesInDir[/COLOR](aDir)
        For Each nextDir In aDir.GetDirectories
            WorkWithDirectory(nextDir)
        Next
    End Sub

    Private Sub WorkWithFilesInDir(ByVal aDir As DirectoryInfo)
             Dim aFile As FileInfo
        For Each aFile In aDir.GetFiles()
            If CLB.Items.Contains(aFile.Name) = True Then
                Else
                CLB.Items.Add(aFile.Name)
            End If
        Next
        End Sub

Acontece que qdo adiciono uma pasta com milhares de ficheiros o programa fica bloqueado até concluir o For Each.. estava a tentar adicionar um BackgroundWorker para fazer isto à parte mas dá-em sempre erro devido à variável "aDir"...

tentei substituir a parte do "WorkWithFilesInDir" por um BackgroundWorker:

ficou tudo assim:

Código:
Private Sub backgroundWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles backgroundWorker.DoWork
        Dim aFile As FileInfo
        For Each aFile In aDir.GetFiles()
            If CLB.Items.Contains(aFile.Name) = True Then
            Else
                CLB.Items.Add(aFile.Name)
            End If
        Next
    End Sub


mas dá o erro de "Error 1 - Name 'aDir' is not declared"

Alguma ideia? :)

Thanks
 
Assim nunca ia funcionar. Tem que ser uma função recursiva.
Código:
    Private Function GetRecursiveDir(ByVal strPath As String) As Integer
        Dim objDir As New DirectoryInfo(strPath & "\")

        For Each d In objDir.GetDirectories
            ListBox1.Items.Add(d.FullName)
            GetRecursiveDir(strPath & "\" & d.Name)
            ListBox1.Items.Add("-")
        Next

        Dim objFile As FileInfo
        For Each objFile In objDir.GetFiles
            ListBox1.Items.Add(objFile.Name + " - " + Math.Round(objFile.Length / 1024).ToString())
        Next
        Return 0
    End Function
Podes chamar isto de qualquer lado da forma: GetRecursiveDir("C:\temp\")

A função recursiva chama-se a si própria cada vez que encontra uma nova directoria. Desta forma, só existe um local onde a directoria é processada. Assim que termina essa directoria, a função termina no local anterior e processa o file/dir seguinte.
 
Última edição pelo moderador:
Assim nunca ia funcionar. Tem que ser uma função recursiva.

Private Function GetRecursiveDir(ByVal strPath As String) As Integer
Dim objDir As New DirectoryInfo(strPath & "\")

For Each d In objDir.GetDirectories
ListBox1.Items.Add(d.FullName)
GetRecursiveDir(strPath & "\" & d.Name)
ListBox1.Items.Add("-")
Next

Dim objFile As FileInfo
For Each objFile In objDir.GetFiles
ListBox1.Items.Add(objFile.Name + " - " + Math.Round(objFile.Length / 1024).ToString())
Next
Return 0
End Function

Podes chamar isto de qualquer lado da forma: GetRecursiveDir("C:\temp\")

A função recursiva chama-se a si própria cada vez que encontra uma nova directoria. Desta forma, só existe um local onde a directoria é processada. Assim que termina essa directoria, a função termina no local anterior e processa o file/dir seguinte.

Vou testar.. mas sim, parece que tem muita lógica ;)
 
Bem muito obrigado! Já adaptei e funciona muito bem :)

agora tenho outra dúvida e não sei se tenho de fazer com "delegate" ou não..

queria fazer a mesma coisa com outro backgroundworker mas para este processo:

Código:
   Dim I As Integer
        For I = 0 To ListBox1.Items.Count - 1
            ListBox1.SetSelected(I, True)
            ListBox1.SetItemChecked(I, True)
            If ListBox2.Items.Contains(ListBox1.SelectedItem.ToString) = True Then
                       Else
                ListBox2.Items.Add(ListBox1.SelectedItem.ToString)
            End If
        Next

isto basicamente passa os Items todos de uma ListBox1 para a ListBox2.. meti esse código todo no backgroundworker e deu erro de :

"Cross-thread operation not valid: Control 'ListBox1' accessed from a thread other than the thread it was created on."

Tenho solução para isto? senão fica assim pq o raio dos backgroundworker já me gastaram imenso tempo! :eek:
 
Bom..

Estive aqui a inventar mas não funciona bem..


Criei o seguinte:
Código:
Delegate Function ListBoxCheck() As String
Código:
Function ListBoxVerifica() As String
 Dim I As Integer
        For I = 0 To ListBox1.Items.Count - 1
            ListBox1.SetSelected(I, True)
            ListBox1.SetItemChecked(I, True)
            If ListBox2.Items.Contains(ListBox1.SelectedItem.ToString) = True Then
                       Else
		 Return Microsoft.VisualBasic.Left(ListBox1.SelectedItem.ToString, 1)               
            End If
      Next
End Function

e Para adicionar o item devolvido na ListBox2

Código:
Private Delegate Sub DelListItem(ByVal sNome As String)
    Private Sub AddListItem(ByVal sNome As String)
        If ListBox2.InvokeRequired Then
            ListBox2.Invoke(New DelListItem(AddressOf AddListItem), sNome)
        Else
            ListBox2.Items.Add(sNome)
        End If
    End Sub

dentro do backgroundworker coloquei:

Código:
Dim NomeItem As string
NomeItem = ListBox2.Invoke(New ListBoxCheck(AddressOf ListBoxVerifica))
AddListItem(NomeItem)
 
Código:
Private Delegate Sub AdicionaElemento_del(ByVal sNome As String, ByVal lista as ListBox)

    Private Sub AdicionaElemento(ByVal sNome As String, ByVal lista as ListBox)
        If not lista.InvokeRequired Then
            lista.Items.Add(sNome)
        End If
    End Sub

Deste modo podes usar qualquer ListBox que tenhas. Agora convém fazeres um que te faça o SetChecked também. Basicamente tudo que involva alterares controlos tens de ter um delegate para isso
 
Back
Topo