Пишу программу. Есть Queue _readedBlocks. С ней работают три функции:
DequeueReaded
public static void EnqueueReaded(Block block)
{
lock (_readedBlocks)
{
_readedBlocks.Enqueue(block);
Monitor.Pulse(_readedBlocks);
}
}
public static Block DequeueReaded()
{
lock (_readedBlocks)
{
if (!_readedBlocks.Any())
{
if (endOfRead)
return null;
Monitor.Wait(_readedBlocks);
}
return _readedBlocks.Dequeue();
}
}
Больше нигде в коде _readedBlocks никак не используется. У меня один поток заполняет _readedBlocks и два потока его опустошают. В какой то момент у меня вылетает исключение "Очередь пуста". Что я делаю не так? По сути же если очередь пуста, поток становится в ожидание. Как только в очередь добавляется элемент, первый из ждущих получает пульс и работает с его добычей, в то время, как второй должен сидеть и ждать, пока заполняющий поток не подтянет еще элементов. Что не тка в этой логике?
Кейс:
Для наглядности я модифицировал твой пример:
lock (_readedBlocks)
{
Console.WriteLine($"Enter: {Thread.CurrentThread.ManagedThreadId}");
if (!_readedBlocks.Any())
{
if (endOfRead)
return null;
Console.WriteLine($"Wait: {Thread.CurrentThread.ManagedThreadId}");
Monitor.Wait(_readedBlocks);
Console.WriteLine($"Release: {Thread.CurrentThread.ManagedThreadId}");
}
Console.WriteLine($"Dequeue: {Thread.CurrentThread.ManagedThreadId}");
return _readedBlocks.Dequeue();
}
Перед exception получился вот такой output:
Wait: 4
Pulse: 3
Enter: 5
Dequeue: 5
Release: 4
Dequeue: 4
Имхо, в твоем случае, самой лайтовой правкой будет обернуть Wait как-нибудь вот так:
do {
Monitor.Wait(_readedBlocks);
} while (!_readedBlocks.Any());
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Написал простого бота для Telegram на C# (консольное приложение), используя библиотеку TelegramBot
Подскажите, как добавить/исправить существующий обработчик bad gateway, сейчас код выглядит вот так:
Нужно сделать бесконечный цикл перемещения объекта: От стартовой позиции на определенное расстояние вправо, пройдя это расстояние, повернутся,...
Где можно взять практические задания по c# , чтобы можно было использовать в реальной работе