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
Eventos e manipuladores de eventos
Multithreading com Formulários e Controles
Delegados e o operador AddressOf