1

我尝试了一些线程池示例。我从MSDN 网站上的斐波那契示例开始,但这不适合超过 64 次计算,所以我用这段代码解决了:

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()函数?

4

1 回答 1

3

您的代码基本上是这样做的:

// 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。如果你不打算等待事件,那么就没有真正需要举办事件,是吗?尽管有人想知道为什么要进行计算然后不使用结果。

于 2013-08-08T14:40:09.857 回答