C#生产者/消费者模式 [英] C# Producer/Consumer pattern

查看:153
本文介绍了C#生产者/消费者模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有简单的一个生产者两位消费者的代码如下
,但输出仅耗费C2。
在我的代码中的任何错误?

I have simple one producer two consumers code as follow but the output are only C2 consuming. any bug in my code?

class Program
{
    static void Main(string[] args)
    {
        Object lockObj = new object();
        Queue<string>  queue = new Queue<string>();
        Producer p = new Producer(queue, lockObj);
        Consumer c1 = new Consumer(queue, lockObj, "c1");
        Consumer c2 = new Consumer(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;
    Object lockObject;
    static int seq = 0;
    public Producer(Queue<string> queue, Object lockObject)
    {
        this.queue = queue;
        this.lockObject = lockObject; 
    }

    public void produce()
    {
        while( seq++ <15) //just testinng 15 items
        {
            lock (lockObject)
            {
                string item = "item" + seq;
                queue.Enqueue(item);
                Console.WriteLine("Producing {0}", item);
                if (queue.Count == 1)
                { // first
                    Monitor.PulseAll(lockObject);
                }
            }
        }
    }

}

public class Consumer
{
    Queue<string> queue;
    Object lockObject;
    string name;
    public Consumer(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)
                { 
                    Monitor.Wait(lockObject);
                    continue; 
                }
                item = queue.Dequeue();
                Console.WriteLine(" {0} Consuming {1}", name, item);
            }
        }
    }
}

和输出

生产ITEM1
C2消费ITEM1

Producing item1 c2 Consuming item1

生产ITEM2
C2消费ITEM2

Producing item2 c2 Consuming item2

生产项目3
C2消费项目3

Producing item3 c2 Consuming item3

生产ITEM4
C2消费ITEM4

Producing item4 c2 Consuming item4

生产ITEM5
C2消费ITEM5

Producing item5 c2 Consuming item5

生产ITEM6
C2消费ITEM6

Producing item6 c2 Consuming item6

生产item7
C2消费item7

Producing item7 c2 Consuming item7

生产item8
C2消费item8

Producing item8 c2 Consuming item8

生产item9
C2消费item9

Producing item9 c2 Consuming item9

生产item10
C2消费item10

Producing item10 c2 Consuming item10

生产第11项
C2消费第11项

Producing item11 c2 Consuming item11

生产item12
C2消费item12

Producing item12 c2 Consuming item12

生产item13
C2消费item13

Producing item13 c2 Consuming item13

生产item14
C2消费item14

Producing item14 c2 Consuming item14

生产item15
C2消费item15

Producing item15 c2 Consuming item15

推荐答案

首先,我无法重现你的问题,在这里两个线程消耗一些物品。我猜你的机器速度更快,但是像万千瓦增加睡眠暗示会解决。
我也建议是,你不要试图同步制片人,我的意思是让他排队的项目一样快,因为它可以让消费者同步看到谁处理每个项目。
我做了一个快速修改,它似乎是做工精细:

First, I can't reproduce your problem, here both threads consume some of the items. I guess your machine is faster but adding Sleep like gw suggest will solve that. What I would also suggest is that you don't try to sync the producer, I mean let it queue items as fast as it can and let the consumers sync to see who handles each item. I made a quick modification and it seems to be working fine:

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);
            }                
        }
    }
}

您也可以增加睡眠消费者循环减慢。

You may also add the sleep to slow down the consumer loops.

这篇关于C#生产者/消费者模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆