Problem Statement
The Producer Consumer problem is a classical Multithreaded problem which involves synchronization among multiple threads which are producing/consuming items from a resource at different speeds.
There are different ways to solve this problem in C#. I would be using the Monitor class for locking and its Wait/Pulse methods for signalling.
The client of the ProducerConsumer Class could use the old Threading API (Thread class) to spin off threads which try to consume/produce items or use TPL to use threads from the ThreadPool.
Code
using System.Collections.Generic; using System.Linq; using System.Threading; namespace MultiThreading { internal class ProducerConsumerProblem { private readonly object _lock = new object(); private readonly Queue<int> queue = new Queue<int>(); public void Produce(int input) { lock (_lock) { queue.Enqueue(input); Monitor.Pulse(_lock); } } public int Consume() { lock (_lock) { while (!queue.Any()) { Monitor.Wait(_lock); } return queue.Dequeue(); } } } }
Test
[TestMethod] public void PoducerConsumerProblem_Should_Succeed() { var producerConsumerProblem = new ProducerConsumerProblem(); Thread.CurrentThread.Name = "Main Consumer Thread"; var t1=new Thread( () => producerConsumerProblem.Produce(1)) {Name = "Producer Thread"}; t1.Start(); producerConsumerProblem.Consume(); var t2 =new Thread( () => { for (int i = 0; i < 10; i++) { producerConsumerProblem.Produce(i); } } ) {Name = "Producer Thread 2"}; t2.Start(); }
Final Words
.NET Framework 4.5 has a Concurrent collection called BlockingCollection which solves the same Producer-Consumer problem. In case you are using a former version of the framework, using Monitor is the simplest way to solve the problem. You can also use Semaphores to restrict Threads to a certain number (maybe depending on the cores of your system).