Udostępnij za pośrednictwem


Porady: korzystanie z puli wątków (C# i Visual Basic)

Wątek puli jest forma wielowątkowości zadania, które są dodawane do kolejki i uruchamiane automatycznie, gdy wątki są tworzone.Aby uzyskać więcej informacji, zobacz Pula wątków (C# i Visual Basic).

W poniższym przykładzie użyto.NET Framework puli wątków, aby obliczyć Fibonacci wynik dla dziesięciu cyfr pomiędzy 20 a 40.Każdy Fibonacci wynik jest reprezentowana przez Fibonacci klasy, która zawiera metodę o nazwie ThreadPoolCallback , która wykonuje obliczenie.Obiekt reprezentujący każdego Fibonacci wartość jest tworzony oraz ThreadPoolCallback metody jest przekazywany do QueueUserWorkItem, który przypisuje dostępne wątku w puli, wykonanie metody.

Ponieważ każdy Fibonacci znajduje się obiekt półlosowe wartości do obliczenia i ponieważ każdy wątek będzie konkurować na czas procesora, nie wie, z wyprzedzeniem, jak długo potrwa dla wszystkich 10 wyników ma zostać obliczona.Dlatego każdy Fibonacci obiekt jest przekazywany wystąpienie ManualResetEvent klasy podczas budowy.Każdy obiekt sygnalizuje obiekt zdarzenia dostarczone po obliczeniu zakończeniu, co umożliwia główny wątek do bloku wykonanie z WaitAll do wszystkich dziesięciu Fibonacci obiekty zostały obliczone z wyników.Main Metoda następnie wyświetla każdy Fibonacci wynik.

Przykład

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 ThreadPoolCallBack(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 = 9 ' 0 to 9

        ' 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.ThreadPoolCallBack, i)
        Next 

        ' Wait for all threads in pool to calculate.
        WaitHandle.WaitAll(doneEvents)
        Console.WriteLine("All calculations are complete.")

        ' Display the results. 
        For i As Integer = 0 To FibonacciCalculations
            Dim f As Fibonacci = fibArray(i)
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
        Next 
    End Sub 

End Module
using System;
using System.Threading;

public class Fibonacci
{
    private int _n;
    private int _fibOfN;
    private ManualResetEvent _doneEvent;

    public int N { get { return _n; } }
    public int FibOfN { get { return _fibOfN; } }

    // Constructor. 
    public Fibonacci(int n, ManualResetEvent doneEvent)
    {
        _n = n;
        _doneEvent = doneEvent;
    }

    // Wrapper method for use with thread pool. 
    public void ThreadPoolCallback(Object threadContext)
    {
        int threadIndex = (int)threadContext;
        Console.WriteLine("thread {0} started...", threadIndex);
        _fibOfN = Calculate(_n);
        Console.WriteLine("thread {0} result calculated...", threadIndex);
        _doneEvent.Set();
    }

    // Recursive method that calculates the Nth Fibonacci number. 
    public int Calculate(int n)
    {
        if (n <= 1)
        {
            return n;
        }

        return Calculate(n - 1) + Calculate(n - 2);
    }
}

public class ThreadPoolExample
{
    static void Main()
    {
        const int FibonacciCalculations = 10;

        // One event is used for each Fibonacci object.
        ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
        Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
        Random r = new Random();

        // Configure and start threads using ThreadPool.
        Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
        for (int i = 0; i < FibonacciCalculations; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);
            fibArray[i] = f;
            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
        }

        // Wait for all threads in pool to calculate.
        WaitHandle.WaitAll(doneEvents);
        Console.WriteLine("All calculations are complete.");

        // Display the results. 
        for (int i= 0; i<FibonacciCalculations; i++)
        {
            Fibonacci f = fibArray[i];
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
        }
    }
}

Oto przykład danych wyjściowych.

launching 10 tasks...
thread 0 started...
thread 1 started...
thread 1 result calculated...
thread 2 started...
thread 2 result calculated...
thread 3 started...
thread 3 result calculated...
thread 4 started...
thread 0 result calculated...
thread 5 started...
thread 5 result calculated...
thread 6 started...
thread 4 result calculated...
thread 7 started...
thread 6 result calculated...
thread 8 started...
thread 8 result calculated...
thread 9 started...
thread 9 result calculated...
thread 7 result calculated...
All calculations are complete.
Fibonacci(38) = 39088169
Fibonacci(29) = 514229
Fibonacci(25) = 75025
Fibonacci(22) = 17711
Fibonacci(38) = 39088169
Fibonacci(29) = 514229
Fibonacci(29) = 514229
Fibonacci(38) = 39088169
Fibonacci(21) = 10946
Fibonacci(27) = 196418

Zobacz też

Informacje

Mutex

WaitAll

ManualResetEvent

Set

ThreadPool

QueueUserWorkItem

ManualResetEvent

Koncepcje

Pula wątków (C# i Visual Basic)

Monitory

Inne zasoby

Wątkowość (C# i Visual Basic)

JAK: Synchronizowanie dostęp do zasobu udostępnionego w środowisku wielowątkowość przy użyciu programu Visual C#.NET

Zabezpieczenia w programie .NET Framework