共用方式為


多執行緒程序的參數和傳回值

更新:2007 年 11 月

因為必須將執行緒類別的建構函式 (Constructor) 傳遞給不使用引數且不傳回值的程序參考,所以在多執行緒應用程式 (Multithreaded Application) 中提供和傳回值並不容易。以下章節將說明一些簡單的方法,來提供參數以及從個別執行緒上的程序傳回值。

提供多執行緒程式的參數

為多執行緒方法呼叫提供參數的最佳做法是,將目標方法包裝在類別之中,接著為此類別定義將當做新執行緒參數的欄位。這種做法的好處是,每次您想要啟動新執行緒時,就可以建立類別的新執行個體以及其本身的參數。例如,假設您有個函式是用來計算三角形的面積,如下列程式碼所示:

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

您可以寫入類別來包裝 CalcArea 函式,並建立欄位以儲存輸入參數,如以下所示:

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

若要使用 AreaClass,您可以建立 AreaClass 物件,並設定 Base 和 Height 屬性,如下列程式碼所示:

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

請注意,TestArea 程序在呼叫 CalcArea 方法之後,不會檢查 Area 欄位的值。由於 CalcArea 是在個別的執行緒上執行,因此如果您在呼叫 Thread.Start 之後立即檢查 Area 欄位,則不保證它已設定好。下一章節將討論從多執行緒程序傳回值的較佳做法。

從多執行緒程序傳回值

從個別執行緒上執行的程序傳回值之所以複雜的原因是,程序不能是函式且無法使用 ByRef 引數。傳回值的最簡單方式是使用 BackgroundWorker 元件管理執行緒,並在工作完成時引發事件,且使用事件處理常式處理結果。

以下範例將藉由引發事件來從個別執行緒上執行的程序傳回值:

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

使用 QueueUserWorkItem 方法的選擇性 ByVal 狀態物件變數,即可提供參數並將值傳至執行緒集區執行緒。執行緒計時器執行緒也支援狀態物件,以達成這個目的。如需執行緒集區和執行緒計時器的詳細資訊,請參閱執行緒共用執行緒計時器

請參閱

概念

執行緒狀態

執行緒共用

執行緒同步處理

事件和事件處理常式

多執行緒應用程式

在表單和控制項使用多執行緒

委派和 AddressOf 運算子

其他資源

元件中的多執行緒