Parâmetros e Valores de Retorno para os Procedimentos Multi-threaded

Fornecer e retornar valores em um aplicativo com vários segmentos é complicado porque o construtor para o segmento de classe deve ser uma referência a um procedimento que não leva argumentos e não retorna nenhum valor.As seções a seguir mostram algumas maneiras simples de fornecer parâmetros e retornar valores de procedimentos em segmentos separados.

Fornecer Parâmetros para os Procedimentos Multi-threaded

A melhor maneira de fornecer parâmetros para um chamada de método com vários segmentos é para quebrar o método de destino em uma classe e definir campos para a classe que servirá como parâmetros para o novo segmento.A vantagem dessa abordagem é que você pode criar uma nova instância da classe, com seus próprios parâmetros, toda vez que quiser iniciar um novo segmento.Por exemplo, suponha que você tenha uma função que calcula a área de um triângulo, como no código a seguir:

Function CalcArea(ByVal Base As Double, ByVal Height As Double) As Double
    CalcArea = 0.5 * Base * Height
End Function

Você pode escrever uma classe que quebra a função CalcArea e cria campos para armazenar parâmetros de entrada, da seguinte maneira:

Class AreaClass
    Public Base As Double
    Public Height As Double
    Public Area As Double
    Sub CalcArea()
        Area = 0.5 * Base * Height
        MsgBox("The area is: " & Area)
    End Sub
End Class

Para usar AreaClass, você pode criar um objeto AreaClass e definir as propriedades Base e Height conforme mostrado no código o seguir:

Protected Sub TestArea()
    Dim AreaObject As New AreaClass
    Dim Thread As New System.Threading.Thread _
                     (AddressOf AreaObject.CalcArea)
    AreaObject.Base = 30
    AreaObject.Height = 40
    Thread.Start()
End Sub

Observe que o procedimento TestArea não verifica o valor do campo Area após chamar o método CalcArea.Como CalcArea é executado em um segmento separado, não se pode garantir que o campo Area será definido se você marcá-lo imediatamente após chamar Thread.Start.A próxima seção discute uma melhor forma para retornar valores de procedimentos com vários segmentos.

Retornar Valores dos Procedimentos Multi-threaded

Retornar valores de procedimentos executados em segmentos separados é complicado pelo fato de que os procedimentos não podem ser funções e não é possível usar argumentos ByRef.A maneira mais fácil de retornar valores é usar o componente BackgroundWorker para gerenciar seus segmentos e disparar um evento quando a tarefa estiver concluída e processar os resultados com um manipulador de eventos.

O exemplo a seguir retorna um valor ao disparar um evento a partir de um procedimento em execução em um segmento separado:

Private Class AreaClass2
    Public Base As Double
    Public Height As Double
    Function CalcArea() As Double
        ' Calculate the area of a triangle.
        Return 0.5 * Base * Height
    End Function
End Class

Private WithEvents BackgroundWorker1 As New System.ComponentModel.BackgroundWorker

Private Sub TestArea2()
    Dim AreaObject2 As New AreaClass2
    AreaObject2.Base = 30
    AreaObject2.Height = 40

    ' Start the asynchronous operation.
    BackgroundWorker1.RunWorkerAsync(AreaObject2)
End Sub

' This method runs on the background thread when it starts.
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
    ByVal e As System.ComponentModel.DoWorkEventArgs) _
    Handles BackgroundWorker1.DoWork

    Dim AreaObject2 As AreaClass2 = CType(e.Argument, AreaClass2)
    ' Return the value through the Result property.
    e.Result = AreaObject2.CalcArea()
End Sub

' This method runs on the main thread when the background thread finishes.
Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, _
    ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
    Handles BackgroundWorker1.RunWorkerCompleted

    ' Access the result through the Result property.
    Dim Area As Double = CDbl(e.Result)
    MsgBox("The area is: " & Area)
End Sub

Você pode fornecer parâmetros e retornar valores para segmentos de pool de segmentos, usando a variável de objeto de estado ByVal opcional do método QueueUserWorkItem.Segmentos timer de segmento também oferecem suporte a um objeto de estado para essa finalidade.Para obter informações sobre o pool de segmento e timers de segmento, consulte Pool de Segmentos e Timers de segmento.

Consulte também

Conceitos

Estados da thread

Pool de Segmentos

Sincronização de Segmento

Eventos e manipuladores de eventos

Aplicativos Multithreaded

Multithreading com Formulários e Controles

Delegados e o operador AddressOf

Outros recursos

Multithreading in Components