FUNCAO BACKGROUND
Fala pessoal blz ?
Tenho uma função que buscaarquivos, gostaria de executar essa função só que ao mesmo tempo gostaria que ela liberasse o form.
Tenho um listbox no qual irei selecionar os computadores que irei executar essa função após selecionar esses computadores irei abrir um outro form que irá mostrar qual o computador que está sendo executado a busca assim como algumas informações como por exemplo uma progressbar como o andamento.
O problema é que quando eu executo a busca o form com as informações [Ô]fica travado[Ô] pois ele está executando a função de procurar alguém tem alguma sugestão ?
A questão também é que se eu mostrar o form frmPesquisando ele não faz a chamada para a função, abaixo está o exemplo.
Obrigado !
Form:
Dim I As Integer
For I = 0 To ListBoxComputadoresAuditados.Items.Count - 1
frmPesquisando.Show()
Dim list As List(Of String) = FileHelper.GetFilesRecursive([Ô]\\[Ô] & ListBoxComputadoresAuditados.Items(I).ToString & [Ô]\C$[Ô])
frmPesquisando.lblComputadorAtual.Text = ListBoxComputadoresAuditados.Items(I).ToString
For Each path In list
MsgBox(path)
Next
Next
A baixo a clase de procurar
Imports System.IO
[ô][ô][ô] <summary>
[ô][ô][ô] This class contains directory helper method(s).
[ô][ô][ô] </summary>
Public Class FileHelper
[ô][ô][ô] <summary>
[ô][ô][ô] This method starts at the specified directory, and traverses all subdirectories.
[ô][ô][ô] It returns a List of those directories.
[ô][ô][ô] </summary>
Public Shared Function GetFilesRecursive(ByVal initial As String) As List(Of String)
[ô] This list stores the results.
Dim result As New List(Of String)
[ô] This stack stores the directories to process.
Dim stack As New Stack(Of String)
[ô] Add the initial directory
stack.Push(initial)
[ô] Continue processing for each stacked directory
Do While (stack.Count > 0)
[ô] Get top directory string
Dim dir As String = stack.Pop
Try
[ô] Add all immediate file paths
result.AddRange(Directory.GetFiles(dir, [Ô]*.txt*[Ô]))
[ô] Loop through all subdirectories and add them to the stack.
Dim directoryName As String
For Each directoryName In Directory.GetDirectories(dir)
stack.Push(directoryName)
Next
Catch ex As Exception
End Try
Loop
[ô] Return the list
Return result
End Function
End Class
Tenho uma função que buscaarquivos, gostaria de executar essa função só que ao mesmo tempo gostaria que ela liberasse o form.
Tenho um listbox no qual irei selecionar os computadores que irei executar essa função após selecionar esses computadores irei abrir um outro form que irá mostrar qual o computador que está sendo executado a busca assim como algumas informações como por exemplo uma progressbar como o andamento.
O problema é que quando eu executo a busca o form com as informações [Ô]fica travado[Ô] pois ele está executando a função de procurar alguém tem alguma sugestão ?
A questão também é que se eu mostrar o form frmPesquisando ele não faz a chamada para a função, abaixo está o exemplo.
Obrigado !
Form:
Dim I As Integer
For I = 0 To ListBoxComputadoresAuditados.Items.Count - 1
frmPesquisando.Show()
Dim list As List(Of String) = FileHelper.GetFilesRecursive([Ô]\\[Ô] & ListBoxComputadoresAuditados.Items(I).ToString & [Ô]\C$[Ô])
frmPesquisando.lblComputadorAtual.Text = ListBoxComputadoresAuditados.Items(I).ToString
For Each path In list
MsgBox(path)
Next
Next
A baixo a clase de procurar
Imports System.IO
[ô][ô][ô] <summary>
[ô][ô][ô] This class contains directory helper method(s).
[ô][ô][ô] </summary>
Public Class FileHelper
[ô][ô][ô] <summary>
[ô][ô][ô] This method starts at the specified directory, and traverses all subdirectories.
[ô][ô][ô] It returns a List of those directories.
[ô][ô][ô] </summary>
Public Shared Function GetFilesRecursive(ByVal initial As String) As List(Of String)
[ô] This list stores the results.
Dim result As New List(Of String)
[ô] This stack stores the directories to process.
Dim stack As New Stack(Of String)
[ô] Add the initial directory
stack.Push(initial)
[ô] Continue processing for each stacked directory
Do While (stack.Count > 0)
[ô] Get top directory string
Dim dir As String = stack.Pop
Try
[ô] Add all immediate file paths
result.AddRange(Directory.GetFiles(dir, [Ô]*.txt*[Ô]))
[ô] Loop through all subdirectories and add them to the stack.
Dim directoryName As String
For Each directoryName In Directory.GetDirectories(dir)
stack.Push(directoryName)
Next
Catch ex As Exception
End Try
Loop
[ô] Return the list
Return result
End Function
End Class
Creio eu que terei que trabalhar com treads correto ?
O background worker vai servir perfeitamente para o que você quer. Claro que poderia trabalhar com threads puramente, mas complicaria um pouco...
KERPLUNK obrigado pela sugestão !
Dei uma analisada e fiz um projetinho de teste mas não consegui verificar o porque o do form fica em [Ô]freeze[Ô] mesmo assim, poderia dar uma olhada ?
Dei uma analisada e fiz um projetinho de teste mas não consegui verificar o porque o do form fica em [Ô]freeze[Ô] mesmo assim, poderia dar uma olhada ?
O problema ali é que você está abrindo um form de dentro do backgroundworker, o que faz ele ser executado no mesmo thread q a sua função que lista os arquivos, travando assim este form.
O que você deve fazer é mostrar este form da thread principal do seu programa, por exemplo no click do botão antes de você iniciar o backgroundworker, e fechar ele depois que o backgroundworker terminar, lembrando que isso deve ser feito na thread principal.
O que você deve fazer é mostrar este form da thread principal do seu programa, por exemplo no click do botão antes de você iniciar o backgroundworker, e fechar ele depois que o backgroundworker terminar, lembrando que isso deve ser feito na thread principal.
Se você precisa colocar um form dentro de um processo separado, o backgroundworker não vai ser aconselhável, nesse caso, use delegates.
Entendi funcionou perfeitamente !
Só mais uma dúvida a chamada eu fiz antes da tread realmente, FORM.SHOW() blz sem erro.
Dentro da tread eu fiz um loop pegando várias computadores, estou percorrendo eles sem erro, a dúvida é eu não consigo atualizar as informações no outro form.
Eu dou um show nele e depois caiu na tread e dentro da tread eu mando atualizar um label só que não muda ele porque ?
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Pesquisando.Show()
atividadeSegundoPlano.RunWorkerAsync()
End Sub
Private Sub executaTrabalho(ByVal processoAtivo As BackgroundWorker)
For i = 0 To cboUsuarios.Items.Count - 1
[ô]ATUALIZO AQUI O LABEL SÓ QUE ELE NÃO ATUALIZA NO FORM.
Pesquisando.lblComputadorAtual.Text = cboUsuarios.Items(i).ToString
Dim list As List(Of String) = FindFiles.GetFilesRecursive([Ô]\\[Ô] & cboUsuarios.Items(i).ToString & [Ô]\C$[Ô])
For Each path In list
Dim strResultado As String = path
MsgBox(path)
Next
Next
End Sub
Só mais uma dúvida a chamada eu fiz antes da tread realmente, FORM.SHOW() blz sem erro.
Dentro da tread eu fiz um loop pegando várias computadores, estou percorrendo eles sem erro, a dúvida é eu não consigo atualizar as informações no outro form.
Eu dou um show nele e depois caiu na tread e dentro da tread eu mando atualizar um label só que não muda ele porque ?
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Pesquisando.Show()
atividadeSegundoPlano.RunWorkerAsync()
End Sub
Private Sub executaTrabalho(ByVal processoAtivo As BackgroundWorker)
For i = 0 To cboUsuarios.Items.Count - 1
[ô]ATUALIZO AQUI O LABEL SÓ QUE ELE NÃO ATUALIZA NO FORM.
Pesquisando.lblComputadorAtual.Text = cboUsuarios.Items(i).ToString
Dim list As List(Of String) = FindFiles.GetFilesRecursive([Ô]\\[Ô] & cboUsuarios.Items(i).ToString & [Ô]\C$[Ô])
For Each path In list
Dim strResultado As String = path
MsgBox(path)
Next
Next
End Sub
Você não pode modificar forms criados em threads diferentes diretamente, para isso o correto é você fazer com que ele execute esta parte de código na thread do form através do método Invoke do mesmo, por exemplo
Da para fazer também usando Lambda ou Delegates anônimas, mas não lembro como elas são no VB já que trabalho praticamente só com C#, então no exemplo criei uma Sub nova mesmo
Só que você deve evitar ao máximo fazer isso se forem muitos itens já que ele torna o processo um pouco mais lento, alias, qualquer loop com muitos itens fica muito mais lento se você ficar atualizando um form
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Pesquisando.Show()
atividadeSegundoPlano.RunWorkerAsync()
End Sub
Private Sub executaTrabalho(ByVal processoAtivo As BackgroundWorker)
For i = 0 To cboUsuarios.Items.Count - 1
[ô]ATUALIZO AQUI O LABEL SÓ QUE ELE NÃO ATUALIZA NO FORM.
Me.Invoke(DirectCast(AddressOf AlterarLabel, Action(Of String)), cboUsuarios.Items(i).ToString)
Dim list As List(Of String) = FindFiles.GetFilesRecursive([Ô]\\[Ô] & cboUsuarios.Items(i).ToString & [Ô]\C$[Ô])
For Each path In list
Dim strResultado As String = path
MsgBox(path)
Next
Next
End Sub
Private Sub AlterarLabel(Texto As String)
Pesquisando.lblComputadorAtual.Text = Texto
End Sub
Da para fazer também usando Lambda ou Delegates anônimas, mas não lembro como elas são no VB já que trabalho praticamente só com C#, então no exemplo criei uma Sub nova mesmo
Só que você deve evitar ao máximo fazer isso se forem muitos itens já que ele torna o processo um pouco mais lento, alias, qualquer loop com muitos itens fica muito mais lento se você ficar atualizando um form
Tópico encerrado , respostas não são mais permitidas