我正在尝试一些线程池示例。我从Fibonacci example on MSDN web site开始,但是this wasn't suitable for more than 64 calculations,所以我已经解决了这段代码:
Imports System.Threading
Module Module1
Public Class Fibonacci
Private _n As Integer
Private _fibOfN
Private _doneEvent As ManualResetEvent
Public ReadOnly Property N() As Integer
Get
Return _n
End Get
End Property
Public ReadOnly Property FibOfN() As Integer
Get
Return _fibOfN
End Get
End Property
Sub New(ByVal n As Integer, ByVal doneEvent As ManualResetEvent)
_n = n
_doneEvent = doneEvent
End Sub
' Wrapper method for use with the thread pool.
Public Sub ThreadPoolCallBackMar(ByVal threadContext As Object)
Dim threadIndex As Integer = CType(threadContext, Integer)
Console.WriteLine("thread {0} started...", threadIndex)
_fibOfN = Calculate(_n)
Console.WriteLine("thread {0} result calculated...", threadIndex)
_doneEvent.Set()
End Sub
Public Function Calculate(ByVal n As Integer) As Integer
If n <= 1 Then
Return n
End If
Return Calculate(n - 1) + Calculate(n - 2)
End Function
End Class
<MTAThread()>
Sub Main()
Const FibonacciCalculations As Integer = 65
' One event is used for each Fibonacci object
Dim doneEvents(FibonacciCalculations) As ManualResetEvent
Dim fibArray(FibonacciCalculations) As Fibonacci
Dim r As New Random()
' Configure and start threads using ThreadPool.
Console.WriteLine("launching {0} tasks...", FibonacciCalculations)
For i As Integer = 0 To FibonacciCalculations
doneEvents(i) = New ManualResetEvent(False)
Dim f = New Fibonacci(r.Next(20, 40), doneEvents(i))
fibArray(i) = f
ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallBackMar, i)
Next
Console.WriteLine("All calculations are complete.")
For i As Integer = 0 To FibonacciCalculations
doneEvents(i).WaitOne()
Dim f As Fibonacci = fibArray(i)
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
Next
Console.Read()
End Sub
End Module
使用WaitOne()
代替WaitAll()
可以解决问题,但问题是:如果我不需要显示结果,那么我不需要第二个循环,但是......没有第二个循环,我要放waitOne()
函数?
答案 0 :(得分:4)
您的代码基本上是这样的:
// start a bunch of threads to do calculations
Console.WriteLine("All calculations are complete."); // This is a lie!
// Wait for the threads to exit
这里的主要问题是,当您拨打Console.WriteLine
时,计算不完整。好吧,他们可能完成,但你不知道,除非你等待事件发现它已被发出信号。
WaitOne
的目的是告诉您计算是否已完成。您的代码应该是这样写的:
For i As Integer = 0 To FibonacciCalculations
doneEvents(i) = New ManualResetEvent(False)
Dim f = New Fibonacci(r.Next(20, 40), doneEvents(i))
fibArray(i) = f
ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallBackMar, i)
Next
Console.WriteLine("All calculations are started. Waiting for them to complete.")
For i As Integer = 0 To FibonacciCalculations
doneEvents(i).WaitOne()
Dim f As Fibonacci = fibArray(i)
Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
Next
Console.WriteLine("All calculations are complete.")
您必须检查事件以了解计算完成。
现在,如果您不需要知道计算是否完成,那么根本不需要WaitOne
。如果你不打算等待活动,那么 事件就没有了真正的需要,是吗?虽然有人想知道你为什么要进行计算然后不使用结果。