Producer Consumer Separate Classes with common BlockingCollection

1.3k views Asked by At

Hoping someone can give some advice regarding the Producer/Consumer Pattern – in particular on how best to achieve a Queue/BlockingCollection which is COMMON to all producers/consumer class instances?

Lets Simplify the scenario; Consider I have;

  • A single Producer class
  • A single single Consumer class.
  • A Service Class which contains instances of both the Producer and Consumer Class. The Service Class simply tells the Producer/Consumer to Start and Stop Work.

The producer will populate a BlockingCollection

The consumer will need to read from that very same BlockingCollection

This is all very easy to do as demonstrated in this article;

https://msdn.microsoft.com/en-us/library/dd287186.aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2

This example essentially has the PRODUCER and the CONSUMER within the same class, referencing a Common Queue/BlockingCollection is of course trivial as the reference to the object is to a private member within the same class.

If I separate the Producer and Consumer into separate Classes, then this raises the question of how to have a common BlockingCollection.

Should I make the "Service Class" a Static/Shared Class, create the BlockingCollection in this class and expose it as a friend/public member?

Where should I put the common Queue?

Thanks in Advance!

1

There are 1 answers

1
sstan On BEST ANSWER

Just design your Producer and Consumer classes to accept the BlockingCollection as a constructor parameter.

Then, wherever you instantiate these classes, and perhaps even more than one of each, just make sure to pass in the same instance of the BlockingCollection to all producers and consumers. Once you've done that, there is no need to keep some other external reference to the BlockingCollection, unless you need it for something else. It's enough that each Producer and Consumer hold a private reference to the same BlockingCollection instance.

Basically, it would look something like this:

public class Producer {
    private BlockingCollection queue;

    public Producer(BlockingCollection queue) {
        this.queue = queue;
    }

    // more code...
}

public class Consumer {
    private BlockingCollection queue;

    public Consumer(BlockingCollection queue) {
        this.queue = queue;
    }

    // more code...
}

// The exact design of this class is up to you. This is just an example.
public class ProducerConsumerBuilder {
    public void BuildProducerAndConsumer(out Producer producer, out Consumer consumer) {
        BlockingCollection queue = new BlockingCollection();
        producer = new Producer(queue);
        consumer = new Consumer(queue);

        // No need to save a reference to "queue" here any longer,
        // unless you need it for something else.
        // It's enough that the producer and consumer each
        // hold their own private reference to the same queue.
    }
}