Vb.net 什么';这是WaitOne()函数的正确用法

Vb.net 什么';这是WaitOne()函数的正确用法,vb.net,multithreading,threadpool,Vb.net,Multithreading,Threadpool,我尝试了一些线程池示例。我从开始,但是,我用以下代码解决: Imports System.Threading Module Module1 Public Class Fibonacci Private _n As Integer Private _fibOfN Private _doneEvent As ManualResetEvent Public ReadOnly Property N() As Integer

我尝试了一些线程池示例。我从开始,但是,我用以下代码解决:

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
导入系统线程
模块1
公共类斐波那契
Private作为整数
私人的
私有事件作为手动重置事件
公共只读属性N()为整数
得到
返回
结束
端属性
作为整数的公共只读属性FibOfN()
得到
返回_fibOfN
结束
端属性
Sub New(ByVal n为整数,ByVal DoneeEvent为手动重置事件)
_n=n
_doneEvent=doneEvent
端接头
'用于线程池的包装器方法。
公共子ThreadPoolCallBackMar(ByVal threadContext作为对象)
Dim threadIndex As Integer=CType(线程上下文,整数)
WriteLine(“线程{0}已启动…”,threadIndex)
_fibOfN=计算(n)
WriteLine(“线程{0}结果已计算…”,threadIndex)
_doneEvent.Set()
端接头
公共函数计算(ByVal n为整数)为整数

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

// start a bunch of threads to do calculations

Console.WriteLine("All calculations are complete."); // This is a lie!

// Wait for the threads to exit
这里的主要问题是,在调用
控制台.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
。如果你不打算等待活动,那么就没有真正的必要举办活动,是吗?尽管有人想知道为什么要进行计算,然后不使用结果。

切换到使用TPL将50行线程压缩为5行。使用
Parallel.For
。还是你坚持用老办法?现在老办法,但新办法真的很有趣…这个问题可以通过应用“马感”来解决。一项非常重要的程序员技能。如果不想显示结果,则不要启动线程。因此,您也不需要WaitOne()。您所说的“不启动线程”是什么意思?在我的例子中,我需要调用一个webservice,因为响应可能非常慢,我希望一次调用多个,而我没有来自WS的响应(这就是为什么我不需要打印结果)。我只需要知道每个线程何时完成…如果你不想等到线程完成。。。那就别等了!不要调用WaitOne/WaitAll函数。我误解你了吗?谢谢你的耐心。我很感激:)