title: Implementing a blocking queue in C#
body: <p>I've use the below code to implement and test a blocking queue. I test the queue by starting up 5 concurrent threads (the removers) to pull items off the queue, blocking if the queue is empty and 1 concurrent thread (the adder) to add items to the queue intermitently. However, if I leave it running for long enough I get an exception because one of the remover threads comes out of a waiting state even when the queue is empty.</p>
  
  <p>Does anyone know why I get the exception? Note, I'm interested in knowing why this doesn't work as opposed to a working solution (as I can just Google that). </p>
  
  <p>I'd greatly appreciate your help.</p>
  
  <pre><code>using System;
  using System.Threading;
  using System.Collections.Generic;
  
  namespace Code
  {
      class Queue&lt;T&gt;
      {
          private List&lt;T&gt; q = new List&lt;T&gt;();
  
          public void Add(T item)
          {
              lock (q)
              {
                  q.Add(item);
                  if (q.Count == 1)
                  {
                      Monitor.Pulse(q);
                  }
              }
          }
  
          public T Remove()
          {
              lock (q)
              {
                  if (q.Count == 0)
                  {
                      Monitor.Wait(q);
                  }
                  T item = q[q.Count - 1];
                  q.RemoveAt(q.Count - 1);
                  return item;
              }
          }
      }
  
      class Program
      {
          static Random r = new Random();
          static Queue&lt;int&gt; q = new Queue&lt;int&gt;();
          static int count = 1;
          static void Adder()
          {
              while (true)
              {
                  Thread.Sleep(1000 * ((r.Next() % 5) + 1));
                  Console.WriteLine("Will try to add");
                  q.Add(count++);
              }
          }
  
          static void Remover()
          {
              while (true)
              {
                  Thread.Sleep(1000 * ((r.Next() % 5) + 1));
                  Console.WriteLine("Will try to remove");
                  int item = q.Remove();
                  Console.WriteLine("Removed " + item);
              }
          }
  
          static void Main(string[] args)
          {
              Console.WriteLine("Test");
  
              for (int i = 0; i &lt; 5; i++)
              {
                  Thread remover = new Thread(Remover);
                  remover.Start();
              }
  
              Thread adder = new Thread(Adder);
              adder.Start();
          }
      }
  }
  </code></pre>