2013-08-08 3 views
1

Я экспериментировал с примерами пула потоков. Я начал с Fibonacci example on MSDN web site, но this wasn't suitable for more than 64 calculations, поэтому я уже решены с этим кодом:Какое правильное использование функции WaitOne()

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

Переключитесь на использование TPL, чтобы свернуть ваши 50 строк резьбы в 5. Используйте 'Parallel.For'. Или вы настаиваете на том, чтобы делать это по-старому? – usr

+0

Прямо сейчас старый путь, но новый способ действительно интересен ... –

+0

Эту проблему можно решить, применив что-то, называемое «чувство лошади». Очень важный программист. Если вы не хотите отображать результат, не запускайте поток. Таким образом, вам не нужен WaitOne(). –

ответ

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. И если вы не собираетесь ждать на мероприятии, то нет никакой реальной необходимости, чтобы имели событие, есть ли? Хотя вы задаетесь вопросом, почему вы собираетесь делать расчет, а затем не используете результат.

+0

Спасибо, за терпение. Я ценю :) –

Смежные вопросы