.NET Framework Boucle de base producteur-consommateur (BlockingCollection)


Exemple

var collection = new BlockingCollection<int>(5);
var random = new Random();

var producerTask = Task.Run(() => {
    for(int item=1; item<=10; item++) 
    {
        collection.Add(item);
        Console.WriteLine("Produced: " + item);
        Thread.Sleep(random.Next(10,1000));
    }
    collection.CompleteAdding();
    Console.WriteLine("Producer completed!");
});

Il est à noter que si vous n'appelez pas collection.CompleteAdding(); , vous pouvez continuer à ajouter à la collection même si votre tâche client est en cours d'exécution. Il suffit d'appeler collection.CompleteAdding(); lorsque vous êtes sûr qu'il n'y a plus d'ajouts. Cette fonctionnalité peut être utilisée pour créer un modèle Producteur multiple vers un consommateur unique dans lequel vous disposez de plusieurs sources alimentant des éléments dans BlockingCollection et un seul consommateur en retirant des éléments et en faisant quelque chose. Si votre BlockingCollection est vide avant que vous appeliez l'ajout complet, le Enumerable de collection.GetConsumingEnumerable() bloquera jusqu'à ce qu'un nouvel élément soit ajouté à la collection ou à BlockingCollection.CompleteAdding (); est appelé et la file d'attente est vide.

var consumerTask = Task.Run(() => {
    foreach(var item in collection.GetConsumingEnumerable())
    {
        Console.WriteLine("Consumed: " + item);
        Thread.Sleep(random.Next(10,1000));
    }
    Console.WriteLine("Consumer completed!");
});
  
Task.WaitAll(producerTask, consumerTask);
       
Console.WriteLine("Everything completed!");