从多线程过程返回值

从多线程过程返回值

由于这些过程不能为函数也不能使用 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)
    MessageBox.Show("The area is: " & Area.ToString)
End Sub


     
  1. classAreaClass2
  2. {
  3. publicdoubleBase;
  4. publicdoubleHeight;
  5. publicdoubleCalcArea()
  6. {
  7. //Calculatetheareaofatriangle.
  8. return0.5*Base*Height;
  9. }
  10. }
  11. privateSystem.ComponentModel.BackgroundWorkerBackgroundWorker1
  12. =newSystem.ComponentModel.BackgroundWorker();
  13. privatevoidTestArea2()
  14. {
  15. InitializeBackgroundWorker();
  16. AreaClass2AreaObject2=newAreaClass2();
  17. AreaObject2.Base=30;
  18. AreaObject2.Height=40;
  19. //Starttheasynchronousoperation.
  20. BackgroundWorker1.RunWorkerAsync(AreaObject2);
  21. }
  22. privatevoidInitializeBackgroundWorker()
  23. {
  24. //AttacheventhandlerstotheBackgroundWorkerobject.
  25. BackgroundWorker1.DoWork+=
  26. newSystem.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork);
  27. BackgroundWorker1.RunWorkerCompleted+=
  28. newSystem.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted);
  29. }
  30. privatevoidBackgroundWorker1_DoWork(
  31. objectsender,
  32. System.ComponentModel.DoWorkEventArgse)
  33. {
  34. AreaClass2AreaObject2=(AreaClass2)e.Argument;
  35. //ReturnthevaluethroughtheResultproperty.
  36. e.Result=AreaObject2.CalcArea();
  37. }
  38. privatevoidBackgroundWorker1_RunWorkerCompleted(
  39. objectsender,
  40. System.ComponentModel.RunWorkerCompletedEventArgse)
  41. {
  42. //AccesstheresultthroughtheResultproperty.
  43. doubleArea=(double)e.Result;
  44. MessageBox.Show("Theareais:"+Area.ToString());
  45. }

可以通过使用 QueueUserWorkItem 方法的可选 ByVal 状态对象变量为线程池线程提供参数和返回值。 线程计时器线程也支持将状态对象用于此目的。 有关线程池和线程计时器的信息,请参见 线程池(C# 和 Visual Basic)线程计时器(C# 和 Visual Basic)

你可能感兴趣的:(多线程)