C# 一个简易的Producer-Consumer工具类

一、关于本文

本文中实现的PCHelper类是一个简易的Producer-Consumer操作工具类。该类可以实现如下目标:由多个线程向其中的一个Queue中写入数据,同时由多个线程负责接收Queue中数据进行处理。

二、工具类代码

/// <summary>
/// Producer-Consumer操作类
/// </summary>
public class PCHelper
{
    readonly object listlock = new object(); //线程锁
    System.Collections.Queue queue = new System.Collections.Queue(); //队列

    /// <summary>
    /// 队列名称:用于标识一个队列
    /// </summary>
    private string _queuename;
    /// <summary>
    /// 队列名称:用于标识一个队列
    /// </summary>
    public string QueueName
    {
        get { return _queuename; }
        private set { _queuename = value; }
    }

    /// <summary>
    /// 队列阈值:队列长度超过阈值后会扔出异常
    /// </summary>
    public uint _threshold;
    /// <summary>
    /// 队列阈值:队列长度超过阈值后会扔出异常
    /// </summary>
    public uint Threshold
    {
        get { return _threshold; }
        private set { _threshold = value; }
    }

    /// <summary>
    /// Producer-Consumer操作类
    /// </summary>
    /// <param name="queuename">队列名</param>
    /// <param name="threshold">队列数据量阈值:超过此阈值会产生异常</param>
    public PCHelper(string queuename = "",uint threshold = 300)
    {
        QueueName = queuename;
        Threshold = threshold;
    }

    /// <summary>
    /// 生产者函数:向队列中添加一条数据
    /// </summary>
    /// <param name="o"></param>
    public void Produce(object o)
    {
        lock (listlock)
        {
            if (queue.Count < Threshold )
            {
                queue.Enqueue(o);
                System.Threading.Monitor.Pulse(listlock);
            }
            else
            {
                throw new Exception("队列长度过长,入队失败");
            }
        }
    }

    /// <summary>
    /// 消费者函数:从队列中取出数据
    /// </summary>
    /// <returns>从队列中取出的第一个数据</returns>
    public object Consume()
    {
        lock (listlock)
        {
            while (queue.Count == 0)
            {
                System.Threading.Monitor.Wait(listlock);
            }
        }
        return queue.Dequeue();
    }

    /// <summary>
    /// 清空数据
    /// </summary>
    public void ClearData()
    {
        lock (listlock)
        {
            queue.Clear();
        }
    }

    /// <summary>
    /// 队列中数据数量
    /// </summary>
    /// <returns></returns>
    public int DataCount()
    {
        int c;
        lock (listlock)
        {
            c = queue.Count;
        }
        return c;
    }

    /// <summary>
    /// 队列中数据类型
    /// </summary>
    /// <returns></returns>
    public Type DataType()
    {
        Type t;
        lock (listlock)
        {
            t = queue.GetType();
        }
        return t;
    }
}

三、测试代码

Program中有Main函数及Main函数需要调用的相关函数。

ProduceLoop函数用于不断向队列queue中写入数据。

ConsumeLoop函数用于不断从队列queue中取出数据。

本段代码中CosumeLoop每次循环的时间间隔被设定要长于ProduceLoop5倍。

因此,当队列到达设定的阈值(本段代码中使用了默认值:300)时,工具类会报出相关异常

class Program
{
    static PCHelper queue;
    static int i;

    static void Main(string[] args)
    {
        queue = new PCHelper("QueueTest");
        i = 0;

        (new System.Threading.Thread(ProduceLoop)).Start(10);
        (new System.Threading.Thread(ConsumeLoop)).Start(50);

        Console.ReadLine();
    }

    /// <summary>
    /// 不断向队列中插入数据
    /// </summary>
    public static void ProduceLoop(object sleeptime)
    {
        while (true)
        {
            queue.Produce(i);
            Console.WriteLine(string.Format(
                "Produce: {0} DataLeft: {1}", i, queue.DataCount()));
            i++;
            System.Threading.Thread.Sleep(int.Parse(sleeptime.ToString()));
        }
    }

    /// <summary>
    /// 不断从队列中取出数据
    /// </summary>
    public static void ConsumeLoop(object sleeptime)
    {
        while (true)
        {
            string temp = queue.Consume().ToString();
            Console.WriteLine(string.Format(
                "Consume: {0} DataLeft: {1}", temp, queue.DataCount()));
            System.Threading.Thread.Sleep(int.Parse(sleeptime.ToString()));
        }
    }
}

四、测试结果

171753_unhy_1425762.png

172215_uuKz_1425762.png

END

转载于:https://my.oschina.net/Tsybius2014/blog/295931

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值