Шаблон Производителя/Потребителя C#

Я не мог компилировать/загружать в VS2019, версия 1.1.0.0 Barcodelib, которая использовалась в Файле Определения Отчета, таким образом, я закончил тем, что регистрировал dll в GAC, который, казалось, работал.

7
задан Tagc 6 September 2017 в 12:38
поделиться

5 ответов

Во-первых, я не могу воспроизвести вашу проблему, здесь оба потока потребляют некоторые элементы. Я предполагаю, что ваша машина быстрее, но добавление Sleep like gw предлагает решить эту проблему. Я бы также посоветовал вам не пытаться синхронизировать производителя, я имею в виду, пусть он ставит элементы в очередь как можно быстрее, а потребители синхронизируются, чтобы видеть, кто обрабатывает каждый элемент. Я сделал быструю модификацию, и, похоже, она работает нормально:

static void Main()
    {
        Object lockObj = new object();
        Queue<string> queue = new Queue<string>();
        Producer p = new Producer(queue);
        Comsumer c1 = new Comsumer(queue, lockObj, "c1");
        Comsumer c2 = new Comsumer(queue, lockObj, "c2");

        Thread t1 = new Thread(c1.consume);
        Thread t2 = new Thread(c2.consume);
        t1.Start();
        t2.Start();

        Thread t = new Thread(p.produce);
        t.Start();

        Console.ReadLine();
    }
}
public class Producer
{
    Queue<string> queue;
    static int seq;
    public Producer(Queue<string> queue)
    {
        this.queue = queue;
    }

    public void produce()
    {
        while (seq++ < 1000) //just testinng 15 items
        {
            string item = "item" + seq;
            queue.Enqueue(item);
            Console.WriteLine("Producing {0}", item);                
        }
    }
}

public class Comsumer
{
    Queue<string> queue;
    Object lockObject;
    string name;
    public Comsumer(Queue<string> queue, Object lockObject, string name)
    {
        this.queue = queue;
        this.lockObject = lockObject;
        this.name = name;
    }

    public void consume()
    {
        string item;
        while (true)
        {
            lock (lockObject)
            {
                if (queue.Count == 0)
                {
                    continue;
                }
                item = queue.Dequeue();
                Console.WriteLine(" {0} Comsuming {1}", name, item);
            }                
        }
    }
}

Вы также можете добавить режим сна, чтобы замедлить потребительские циклы.

6
ответ дан 6 December 2019 в 21:17
поделиться

В целях тестирования попробуйте добавить временную задержку в код потребителя. Может случиться так, что «потребление» происходит так быстро, что один потребительский поток очищает очередь до того, как другой потребительский поток получит шанс.

(править)

Как я и подозревал, добавление

Thread.Sleep ( 500);

внутри потребительского потока (для имитации некоторой продолжительной обработки) приводит к использованию обоих потоков.

4
ответ дан 6 December 2019 в 21:17
поделиться

Добавлен Thread.Sleep (500); в Consumer.comsume

у меня есть следующее:

c2 Comsuming item1 c1 Потребление предмета 2 c2 Потребление item3 c1 Потребление предмета 4 c2 Потребление предмета 5 c1 Потребление предмета 6 c2 Потребление предмета 7 c1 Расходуется item8 ..... результат не является неопределенным после добавления сна.

0
ответ дан 6 December 2019 в 21:17
поделиться

Ваш производитель вызывает Monitor.PulseAll только тогда, когда счетчик очереди равен 1, что будет не очень часто, поскольку производитель не делает ничего существенного, это означает, что первый поток потребления через шлюз получает возможность исключить из очереди первый элемент, второй поток потребления не увидит никаких элементов в очереди и, таким образом, попадет в Monitor.Wait, и Pulse больше не повторится (возможно, пока все, кроме последнего элемент остался), так что второй поток будет сидеть в этом ожидании бесконечно.

2
ответ дан 6 December 2019 в 21:17
поделиться

Я запустил ваш код, и у вас были всплески c1, поглощающие и всплески c2. Вы можете просто проверить эту ссылку в msdn: Как: Синхронизировать источник и поток потребителя (Руководство по программированию C #)

0
ответ дан 6 December 2019 в 21:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: