Redis实现队列
操作类
将数据加入redis,然后用多线程去处理队列内的数据
public class ErpQueue
{
public static Thread Erp_OrderThread;//订单处理线程
private static bool Erp_flag = true;//标识
private static bool Erp_autoResetEventFlag = false;//事件重置标识
private static AutoResetEvent Erp_aEvent = new AutoResetEvent(false);
static ErpQueue()
{
//初始化执行线程
Erp_OrderThread = new Thread(ERPOrderDataProcess);
CacheHelper.Init(3);//初始化redis,并指向对应的库这里指向的时3号库
}
/// <summary>
/// 队列添加数据
/// </summary>
/// <param name="order"></param>
public static void AddQueue(OrderDTO order)
{
//入队
try
{
//将对象转成字符串,存入队列
string OrderInfo = JsonConvert.SerializeObject(order);
//将数据加入队列
CacheHelper.EnqueueListLeftPush("ErpOrder", OrderInfo);
if (Erp_autoResetEventFlag)
{
Erp_aEvent.Set();
}
long count = CacheHelper.EnqueueListLength("ErpOrder");
//这里也可以写个日志记录一下订单进入的时候队列的状态信息
}
catch (Exception ex)
{
//reids没有开启
//这里可以记录日志
}
}
/// <summary>
/// 开启循环数据出队处理
/// </summary>
private static void ERPOrderDataProcess()
{
while (Erp_flag)
{
//判断队列的长度
long count = CacheHelper.EnqueueListLength("ErpOrder");
if (count > 0)
{
Erp_autoResetEventFlag = false;
for (int i = 0; i < count; i++)
{
//出队
string orderInfo = CacheHelper.DequeueListPopLeft("ErpOrder");
if (orderInfo == "-1")
{
//没有数据直接返回
break;
}
else
{
//处理数据
DataHandle(orderInfo);
}
}
}
else
{
//如果队列内没有要处理的数据了,就先暂停线程
Erp_autoResetEventFlag = true;
Erp_aEvent.WaitOne();
}
}
}
/// <summary>
/// 退出线程
/// </summary>
public static void ExitThread()
{
Erp_flag = false;
Erp_aEvent.Set();//恢复线程执行
}
/// <summary>
/// 开启线程
/// </summary>
public static void StartThread()
{
Erp_flag = true;
Erp_OrderThread.Start();
}
/// <summary>
/// 数据处理
/// </summary>
/// <param name="OrderInfo">订单信息</param>
private static void DataHandle(string OrderInfo)
{
//这里时将从Redis中读取出来的数据转会对象进行处理
OrderDTO order = JsonConvert.DeserializeObject<OrderDTO>(OrderInfo);
bool start = DateTime.Now > order.TimeRecord.AddMinutes(5);
if (start)
{
//判断订单进入时间是否大于五分钟,后续处理
}
else
{
//没有五分钟重新入队到达队尾
CacheHelper.EnqueueListLeftPush("ErpOrder", OrderInfo);
}
}
}
redis帮助类
注意事项
- 要在项目启动的时候就直接启动线程,项目关闭时也要将该线程关闭
- 启动线程调用 ErpQueue.StartThread();关闭线程调用 ErpQueue.ExitThread();
- 这里用到的包是:StackExchange.Redis
- 使用左侧入队后面处理数据就必须用左侧出队,入队和出队的方向一定要是一样的,不然会出现数据处理的但是任然存在在队列里的情况