I have a producer-consumer scenario in ASP.NET. I designed a Producer
class, a Consumer
class and a class for holding the shared objects and responsible for communication between Producer and Consumer, lets call it Mediator
. Because I fork the execution path at start-up (in parent object) and one thread would call Producer.Start()
and another thread calls Consumer.Start()
, I need to pass a reference of Mediator
to both Producer
and Consumer
(via Constructor
). Mediator
is a smart class which will optimize many things like length of it's inner queue but for now consider it as a circular blocking queue. Producer
would enqueues new objects to Mediator
until the queue gets full and then Producer
would block. Consumer
dequeues objects from Mediator
until there's nothing in the queue. For signaling between threads, I implemented two methods in Mediator
class: Wait()
and Pulse()
. The code is something like this:
Class Mediator
{
private object _locker = new object();
public void Wait()
{
lock(_locker)
Monitor.Wait(_locker);
}
public void Pulse()
{
lock(_locker)
Monitor.Pulse(_locker);
}
}
// This way threads are signaling:
Class Consumer
{
object x;
if (Mediator.TryDequeue(out x))
// Do something
else
Mediator.Wait();
}
Inside Mediator I use this.Pulse()
every time something is Enqueued or Dequeued so waiting threads would be signaled and continue their work.
But I encounter deadlocks and because I have never used this kind of design for signaling threads, I'm not sure if something is wrong with the design or I'm doing something wrong elsewhere ?
Thanks