1、
1)WaitHandle.WaitAny 方法和WaitHandle.WaitAll方法的区别在于,WaitAny方法只等待指定数组中的任一元素收到信号。
2)我们使用WaitHandle.WaitAny 方法完成一个示例,这个示例同时使用5个线程完成相同的工作:计算从1到2000的累加,哪个线程最先完成计算任务,就终止其它正在计算的线程。为了增强效果,我们指定最后一个线程的优先级最高,结果应是最后一个线程最先完成计算,其它线程被终止
2、代码如下:
Imports System Imports System.Threading Imports System.Diagnostics Imports System.Diagnostics.ThreadState Module Module1_ Sub Main() '完成任务的线程号 Dim finishedid As Integer '自己创建线程对象数组(不使用.NET的线程池),共5个线程 Dim mythread(4) As Thread '分别给每个线程创建一个AutoResetEvent Dim threadevent(4) As AutoResetEvent For i = 0 To mythread.GetUpperBound(0) mythread(i) = New Thread(AddressOf mythreadrun) threadevent(i) = New AutoResetEvent(False) mythread(i).Name = "thread_" & i Next Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程") mythread(4).Priority = ThreadPriority.AboveNormal '执行线程 For i = 0 To mythread.GetUpperBound(0) mythread(i).Start(threadevent(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 & "号线程完成任务,计算完毕!") End Sub Public Sub mythreadrun(ByVal threadevent As Object) Dim mynum As Integer Dim jg As ULong = 0 Try For mynum = 1 To 2000 jg += mynum Thread.Sleep(5) Next Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程运行完毕!") Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>计算结果为:" & jg) Catch Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程异常终止!") '终止线程 Thread.CurrentThread.Abort() Finally CType(threadevent, AutoResetEvent).Set() End Try End Sub End Module
3、效果如下:
4、代码分析如下:
1) 创建一个简单的线程池以及每个线程使用的AutoResetEvent
'完成任务的线程号
Dim finishedid As Integer
'自己创建线程对象数组(不使用.NET的线程池),共5个线程
Dim mythread(4) As Thread
'分别给每个线程创建一个AutoResetEvent
Dim threadevent(4) As AutoResetEvent
注意finishedid将保存最先完成任务的线程号
2)对线程池的每个线程对象初始化,指定名称。同时也初始化AutoResetEvent数组
For i = 0 To mythread.GetUpperBound(0)
mythread(i) = New Thread(AddressOf mythreadrun)
threadevent(i) = New AutoResetEvent(False)
mythread(i).Name = "thread_" & i
Next
3)指定4号线程的优先级,比其它线程池的线程要高,同时启动线程,将AutoResetEvent数组中的元素做为参数传进线程中
mythread(4).Priority = ThreadPriority.AboveNormal
'执行线程
For i = 0 To mythread.GetUpperBound(0)
mythread(i).Start(threadevent(i))
Next
4) 等待其中一个线程完成累加:
finishedid = WaitHandle.WaitAny(threadevent)
将其它未完成任务的线程终止 :
For i = 0 To mythread.GetUpperBound(0)
If i <> finishedid Then
mythread(i).Abort()
End If
Next
5)线程函数中完成累加,并输出结果
For mynum = 1 To 2000
jg += mynum
Thread.Sleep(5)
Next
Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程运行完毕!")
Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>计算结果为:" & jg)
6)设置 AutoResetEvent对象状态
Finally
CType(threadevent, AutoResetEvent).Set()