一、关于本文
本文中实现的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()));
}
}
}
四、测试结果
END