4 sur 6 ont trouvé cela utile - Évaluez ce sujet

Comment : utiliser un pool de threads (Guide de programmation C#)

Un pool de threads est une collection de threads qui peut être utilisée pour effectuer un certain nombre de tâches en arrière-plan. (Consultez Utilisation de threads pour obtenir des informations générales.) Cela laisse le thread principal libre pour effectuer d'autres tâches de façon asynchrone.

Les pools de threads sont souvent employés dans des applications serveur. Chaque requête entrante est assignée à un thread du pool de threads, pour que la demande puisse être traitée de façon asynchrone, sans lier le thread principal ou différer le traitement de demandes suivantes.

Une fois qu'un thread du pool complète sa tâche, il est retourné à une file d'attente de threads en attente, où il peut être réutilisé. Cette réutilisation permet aux applications d'épargner le coût de la création d'un thread pour chaque tâche.

Les pools de threads ont en général un nombre maximal de threads. Si tous les threads sont occupés, des tâches supplémentaires sont placées dans la file d'attente jusqu'à ce qu'ils puissent être gérés à mesure que les threads deviennent disponibles.

Vous pouvez implémenter votre propre pool de threads, mais il est plus facile d'utiliser le pool de threads fourni par .NET Framework par le biais de la classe ThreadPool.

L'exemple suivant utilise le pool de threads .NET Framework pour calculer le résultat Fibonacci pour dix nombres entre 20 et 40. Chaque résultat Fibonacci est représenté par la classe Fibonacci, qui fournit une méthode appelée ThreadPoolCallback qui effectue le calcul. Un objet représentant chaque valeur de Fibonacci est créé, et la méthode ThreadPoolCallback est passée à QueueUserWorkItem, qui assigne un thread disponible du pool pour exécuter la méthode.

Parce que chaque objet Fibonacci se voit donner une valeur semi aléatoire à calculer, et parce que chacun des dix threads sera en concurrence pour le temps processeur, il n'y a aucun moyen de savoir à l'avance le temps qu'il faudra pour calculer les dix résultats. C'est pourquoi une instance de la classe ManualResetEvent est passée à chaque objet Fibonacci pendant la construction. Chaque objet signale à l'objet événement fourni que son calcul est terminé, ce qui permet au thread principal de bloquer l'exécution avec WaitAll jusqu'à ce que les dix objets Fibonacci aient calculé un résultat. La méthode Main affiche ensuite chaque résultat Fibonacci.

Exemple

using System;
using System.Threading;

public class Fibonacci
{
    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 int N { get { return _n; } }
    private int _n;

    public int FibOfN { get { return _fibOfN; } }
    private int _fibOfN;

    private ManualResetEvent _doneEvent;
}

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 launch 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 calculation...
        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);
        }
    }
}

Résultat de l'exemple

 
launching 10 tasks...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
result calculated...
all calculations complete
Fibonacci(22) = 17711
Fibonacci(25) = 75025
Fibonacci(32) = 2178309
Fibonacci(36) = 14930352
Fibonacci(32) = 2178309
Fibonacci(26) = 121393
Fibonacci(35) = 9227465
Fibonacci(23) = 28657
Fibonacci(39) = 63245986
Fibonacci(22) = 17711

Voir aussi

Cela vous a-t-il été utile ?
(1500 caractères restants)
Contenu de la communauté Ajouter
Annotations FAQ