Проблема, похоже, в последней части кода. Вы удерживаете блокировку, когда выполняете это:
else
{
if (number == -99)
{
Console.WriteLine("Consumer thread exit");
return;
}
Monitor.Exit(locker);
_wh.WaitOne(); // No more tasks - wait for a signal
}
То есть, если number == 99
, метод возвращается без снятия блокировки.
Ваш ConsumeNumbers
метод слишком сложен. Вы можете упростить это:
while (true)
{
_wh.WaitOne();
lock (locker)
{
if (number == -99)
break;
if (number > -1)
{
// process the number.
number = -1;
}
}
}
Это будет делать то же самое, и код намного проще.
Кстати, конструкция:
lock (locker)
{
// do stuff here
}
совпадает с:
Monitor.Enter(locker);
try
{
// do stuff here
}
finally
{
Monitor.Exit(locker);
}