How to wait for the end of a Thread and how to receive values from it?

2

I'm working on a situation that requires the use of multiprocessing.

I need to read files and a bunch of processes that can take some time. During this process, I want to display a sort of window to user (Aguarde...) without compromising the UI thread and without causing those whitish that occur when the graphical interface is no longer updated.

However, it is difficult to know when the thread has finished its work because the process has no set time and can vary according to the volume of information handled and the configuration of the machine. On the internet, I found the join method, which is responsible for waiting for the end of thread processing. In the meantime, I'm forced to stipulate a time for him to exit the standby mode and as I mentioned before, the process may take a little longer.

My thread runs a method that has a return and I am also not able to retrieve the information from this method. I searched the internet, but it was not clear yet. I do not know how to retrieve the data handled by the thread .

My thread runs a method that captures database information, compares it to a text file, and then returns a ArrayList with the discrepant data. The problem is to know when the process has finished and receive the result of this method.

Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles Button2.Click
    Dim OPF As New OpenFileDialog
    Dim Caminho As String
    Dim Aviso As New frmWarning
    Dim ListaEntradas As ArrayList

    If IO.Directory.Exists(Path) Then
        Caminho = Path
    Else
        Caminho = Path.Substring(1, 3)
    End If

    With OPF
        .InitialDirectory = Caminho
        .ShowDialog()
    End With

    Aviso.Show()
    Dim compara As New Thread(AddressOf TDNFEntradas)
    compara.Start(OPF.FileName)

    'ListaEntradas = (E AGORA? COMO RECEBER A LISTA DA THREAD?)
    Aviso.Close()


End Sub

Private Function TDNFEntradas(ByVal Endereco As String) As ArrayList
    Dim NFentradas As New ArrayList
    Dim Mensagem As New frmWarning
    Dim Lista As New ArrayList

    HabilitarControlesNF(False) ' Desabilita controles do formulario
    NFentradas = CapturarNotas(Endereco, 0) ' Carrega Numeros das Notas dentro de um arrayList
    Lista = CompNotasEntrada(NFentradas) ' Compara dados da lista com o banco e retorna as diferenças numa outra lista
    HabilitarControlesNF(True) 'Habilita controles do formulario

    Return Lista 'Retorna lista com discrepancias

End Function
    
asked by anonymous 10.04.2014 / 15:33

1 answer

1

To get the return of a Function executed on Thread , you need to use a BackgroundWorker :

Private WithEvents BackgroundWorker1 As New System.ComponentModel.BackgroundWorker

Your final code will look something like this:

Private Class Entradas
    Public CaminhoArquivo As String
    Function TDNFEntradas() As ArrayList
        Dim NFentradas As New ArrayList
        Dim Mensagem As New frmWarning
        Dim Lista As New ArrayList

        HabilitarControlesNF(False) ' Desabilita controles do formulario
        NFentradas = CapturarNotas(CaminhoArquivo, 0) ' Carrega Numeros das Notas dentro de um arrayList
        Lista = CompNotasEntrada(NFentradas) ' Compara dados da lista com o banco e retorna as diferenças numa outra lista
        HabilitarControlesNF(True) 'Habilita controles do formulario

        Return Lista 'Retorna lista com discrepancias

    End Function
End Class

Private Sub Button2_Click_1(sender As Object, e As EventArgs) Handles Button2.Click
    Dim OPF As New OpenFileDialog
    Dim Caminho As String
    Dim Aviso As New frmWarning
    Dim ListaEntradas As ArrayList
    Dim ClasseEntradas As New Entradas

    If IO.Directory.Exists(Path) Then
        Caminho = Path
    Else
        Caminho = Path.Substring(1, 3)
    End If

    With OPF
        .InitialDirectory = Caminho
        .ShowDialog()
    End With

    Entradas.CaminhoArquivo = OPF.FileName
    Aviso.Show()

    ' Executar Thread com Worker
    BackgroundWorker1.RunWorkerAsync(Entradas)
End Sub 

' Este é o método que realiza o trabalho em Thread.
Private Sub BackgroundWorker1_DoWork(
    ByVal sender As Object, 
    ByVal e As System.ComponentModel.DoWorkEventArgs
    ) Handles BackgroundWorker1.DoWork

    Dim Entradas As ClasseEntradas = CType(e.Argument, Entradas)
    ' Retorne o valor por e.Result
    e.Result = Entradas.TDNFEntradas()
End Sub 

' Este método executa quando a Thread termina
Private Sub BackgroundWorker1_RunWorkerCompleted(
    ByVal sender As Object,
    ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs
    ) Handles BackgroundWorker1.RunWorkerCompleted

    ' Obter Resultado
    Dim Lista As ArrayList = CDbl(e.Result)
    ' Trate aqui sua lista
End Sub

Basically I've adapted this article here: link

    
10.04.2014 / 16:25