Parámetros y valores devueltos para procedimientos multiproceso
Actualización: noviembre 2007
Suministrar y devolver valores en aplicaciones multiproceso es complicado, porque se debe pasar una referencia a un procedimiento que no tome ningún argumento ni devuelva ningún valor al constructor de la clase de subproceso. Las secciones siguientes muestran formas sencillas de suministrar parámetros y devolver valores de procedimientos en subprocesos separados.
Suministrar parámetros para procedimientos multiproceso
La mejor forma de suministrar parámetros para una llamada a un método multiproceso es ajustar el método de destino en una clase y definir campos para dicha clase que servirán como parámetros para el nuevo subproceso. La ventaja de este planteamiento es que se puede crear una nueva instancia de la clase, con sus propios parámetros, cada vez que se desee iniciar un nuevo subproceso. Por ejemplo, suponga que tiene una función que calcula el área de un triángulo, como en el código siguiente:
Function CalcArea(ByVal Base As Double, ByVal Height As Double) As Double
CalcArea = 0.5 * Base * Height
End Function
Se puede escribir una clase que encapsule la función CalcArea y cree campos para almacenar parámetros de entrada de la forma indicada a continuación:
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 utilizar AreaClass, puede crear un objeto AreaClass y establecer las propiedades Base y Height como se muestra en el código siguiente:
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
Tenga en cuenta que el procedimiento TestArea no comprueba el valor del campo Area después de llamar al método the CalcArea. Como the CalcArea se ejecuta en un subproceso independiente, no se garantiza que se establezca el valor del campo Area si se comprueba inmediatamente después de llamar a Thread.Start. La sección siguiente explica una mejor forma de devolver valores de procedimientos multiproceso.
Devolver valores de procedimientos multiproceso
Devolver valores de procedimientos multiproceso que se ejecutan en subprocesos separados es complicado por el hecho de que los procedimientos no pueden ser funciones y no pueden utilizar argumentos ByRef. La forma más sencilla de devolver valores consiste en utilizar el componente BackgroundWorker para administrar los subprocesos, generar un evento cuando finalice la tarea y procesar los resultados con un controlador de eventos.
El ejemplo siguiente devuelve un valor mediante la generación de un evento desde un procedimiento que se ejecuta en un subproceso 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
Se pueden proporcionar parámetros y valores devueltos a subprocesos de grupos de subprocesos, mediante la variable opcional de objeto de estado ByVal del método QueueUserWorkItem. Los subprocesos de temporizador de subproceso admiten también un objeto de estado con este propósito. Para obtener información sobre la agrupación de subprocesos y los temporizadores de subprocesos, vea Agrupación de subprocesos y Temporizadores de subprocesos.
Vea también
Conceptos
Eventos y controladores de eventos
Subprocesamiento múltiple con formularios y controles
Los delegados y el operador AddressOf