VB.NET并行与分布式编程(6)-线程与内核同步[7]

我们继续扩展刚才的话题,再次使用WaitAny完成一个简单的任务,求100以内阶乘之和

 

完成这个任务我们先来解决几个问题

1、如何将线程计算结果传出来,参数可以传入,而且只能传入一个,如何传入多个参数,并输出多个参数?

1)最经典的方法是定义一个类,这个类存放了传入的参数和传出的参数

Imports System
Imports System.Threading
Imports System.Diagnostics
Imports System.Diagnostics.ThreadState


Module Module1

    <MTAThread()> _
    Sub Main()





        '完成任务的线程号
        Dim finishedid As Integer
        '自己创建线程对象数组(不使用.NET的线程池),共5个线程
        Dim mythread(4) As Thread
        '分别给每个线程创建一个线程信号类对象,保存AutoResetEvent对象和计算结果
        Dim calculateifno(4) As CalculateIfno
        Dim threadevent(4) As AutoResetEvent

        For i = 0 To mythread.GetUpperBound(0)
            mythread(i) = New Thread(AddressOf mythreadrun)
            mythread(i).Name = "thread_" & i
        Next
        Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程")
        mythread(4).Priority = ThreadPriority.AboveNormal
        '设置线程执行前相关参数,并执行线程,将参数对象传入线程
        For i = 0 To mythread.GetUpperBound(0)
            '设置参数对象
            calculateifno(i) = New CalculateIfno
            calculateifno(i).threadevent = New AutoResetEvent(False)
            calculateifno(i).result = 0
            threadevent(i) = calculateifno(i).threadevent
            '将参数对象传入线程并执行
            mythread(i).Start(calculateifno(i))
        Next
        '等待其中一个线程完成累加,然后将其它未完成任务的线程终止 
        finishedid = WaitHandle.WaitAny(threadevent)
        For i = 0 To mythread.GetUpperBound(0)
            If i <> finishedid Then
                mythread(i).Abort()
            End If
        Next
        '线程执行完毕
        Console.WriteLine(Now.ToLongTimeString & "    " & finishedid & "号线程完成任务,计算完毕!" & Environment.NewLine & "计算结果为:" & calculateifno(finishedid).result)
    End Sub
    Public Class CalculateIfno
        Private _threadevent As AutoResetEvent
        Private _result As Long
        Public Property threadevent As AutoResetEvent
            Get
                Return _threadevent
            End Get
            Set(ByVal value As AutoResetEvent)
                _threadevent = value
            End Set

        End Property
        Public Property result As Long
            Get
                Return _result
            End Get
            Set(ByVal value As Long)
                _result = value
            End Set
        End Property
    End Class

    Public Sub mythreadrun(ByVal calculateifno As Object) As Integer
        Dim mynum As Integer
        Dim jg As Long = 0
        Try
            For mynum = 1 To 1000
                jg += mynum
                Thread.Sleep(5)
            Next
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程运行完毕!")
        Catch
            Console.WriteLine(Thread.CurrentThread.Name & "  " & Now.ToLongTimeString & "线程异常终止!")
            '终止线程
            Thread.CurrentThread.Abort()
        Finally
            CType(calculateifno, CalculateIfno).threadevent.Set()
            CType(calculateifno, CalculateIfno).result = jg
        End Try
    End Sub
End Module

 

 以上代码有几个重点要分析一下

1)VB.NET类的属性定义

  Public Class CalculateIfno
        Private _threadevent As AutoResetEvent
        Private _result As Long
        Public Property threadevent As AutoResetEvent
            Get
                Return _threadevent
            End Get
            Set(ByVal value As AutoResetEvent)
                _threadevent = value
            End Set

        End Property
        Public Property result As Long
            Get
                Return _result
            End Get
            Set(ByVal value As Long)
                _result = value
            End Set
        End Property
    End Class 

 

上述类定义中

  Public Property threadevent As AutoResetEvent
            Get
                Return _threadevent
            End Get
            Set(ByVal value As AutoResetEvent)
                _threadevent = value
            End Set

        End Property
上段代码定义了一个属性,可以理解为“自动实现的属性”,可以快速指定类的属性,而无需编写代码对该属性执行 GetSet 操作。 在为自动实现的属性编写代码时,除了创建关联的 GetSet 过程之外,Visual Basic 编译器还会自动创建一个私有字段来存储该属性变量。

 2)线程函数中对传进来的对象的相关属性的赋值和操作

        Finally
            CType(calculateifno, CalculateIfno).threadevent.Set()
            CType(calculateifno, CalculateIfno).result = jg
        End Try

3)读取线程传出来的结果

        Console.WriteLine(Now.ToLongTimeString & "    " & finishedid & "号线程完成任务,计算完毕!" & Environment.NewLine & "计算结果为:" & calculateifno(finishedid).result)

 

运行结果如下:


VB.NET并行与分布式编程(6)-线程与内核同步[7]
 

你可能感兴趣的:(VB.NET)