Condividi tramite


Parametri e valori restituiti per routine multithreading

Aggiornamento: novembre 2007

L'invio e la restituzione di valori in un'applicazione multithreading è un processo complesso, perché è necessario che il costruttore della classe di thread riceva un riferimento a una routine che non riceve alcun argomento e non restituisce alcun valore. Nelle sezioni seguenti sono indicati alcuni semplici metodi per l'inserimento di parametri e la restituzione di valori da routine su thread diversi.

Inserimento di parametri per routine multithreading

Il modo migliore per inserire i parametri per una chiamata di metodo multithreading consiste nel racchiudere il metodo desiderato in una classe e definire per tale classe dei campi che serviranno da parametri per il nuovo thread. Il vantaggio di questo approccio è dato dalla possibilità di creare una nuova istanza della classe, con parametri propri, ogni volta che si desidera iniziare un nuovo thread. Si supponga, ad esempio, di avere una funzione che calcola l'area di un triangolo, come nel codice che segue:

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

È possibile scrivere una classe che racchiuda la funzione CalcArea e crei i campi in cui memorizzare i parametri di input, come nell'esempio seguente:

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

Per utilizzare AreaClass, è possibile creare un oggetto AreaClass e impostare le proprietà Base e Height come mostrato nel codice che segue:

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

Si noti che la routine TestArea non verifica il valore del campo Area dopo che è stato chiamato il metodo CalcArea. Dato che CalcArea viene eseguito su un thread separato, il campo Area non sarà necessariamente impostato se lo si controlla subito dopo avere chiamato Thread.Start. Nella sezione che segue è illustrato un metodo più efficace per la restituzione di valori dalle routine multithreading.

Restituzione di valori da routine multithreading

La restituzione di valori da routine eseguite su thread diversi è complicata dal fatto che le routine non possono essere funzioni e non possono utilizzare argomenti ByRef. Il modo più semplice per eseguire la restituizione di valori consiste nell'utilizzare il componente BackgroundWorker per gestire i thread e generare un evento una volta completata l'attività, quindi elaborare i risultati tramite un gestore eventi.

L'esempio seguente restituisce un valore generando un evento da una routine eseguita su un thread separato:

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

La variabile facoltativa dell'oggetto di stato ByVal del metodo QueueUserWorkItem consente di fornire parametri e restituire valori ai thread del pool di thread. Un oggetto di stato viene supportato a questo scopo anche dai thread dei timer di thread. Per informazioni sul pooling dei thread e i timer di thread, vedere Pooling dei thread e Timer di thread.

Vedere anche

Concetti

Stati di thread

Pooling dei thread

Sincronizzazione di thread

Eventi e gestori eventi

Applicazioni multithread

Operazioni multithread con form e controlli

Delegati e operatore AddressOf

Altre risorse

Multithreading nei componenti