多线程数据写入队列,异步线程进行批量处理

设计目的:

在多线程环境中,多线程处理数据时,如果每线程都单独写数据库,性能低下。因此,为提高性能,数据需批量写到数据库中。出于此目的,进行了数据队列的设计:

 

实现代码:

 

  1 /// <summary>
  2     /// 多线程异步推送数据,一线程异步批量处理数据
  3     /// </summary>
  4     /// <typeparam name="T"></typeparam>
  5     public abstract class SingleThreadQueue<T>
  6     {
  7         protected List<T> queue;
  8         private Action _beforAction;//在批量执行前执行的方法
  9         private Action _afterAction;//在批量执行完成后执行的方法  
 10         private bool _runing = false;
 11         private int _maxCount, _maxSize;
 12 
 13         /// <summary>
 14         /// 
 15         /// </summary> 
 16         /// <param name="maxCount">每次最大处理数</param>
 17         /// <param name="maxSize">缓冲最大数</param>
 18         /// <param name="beforAction">开始执行处理前的动作</param>
 19         /// <param name="afterAction">所有数据处理完成后的动作</param>
 20         public SingleThreadQueue(int maxCount, int maxSize, Action beforAction = null, Action afterAction = null)
 21         {
 22             this.queue = new List<T>();
 23             this._beforAction = beforAction;
 24             this._afterAction = afterAction;
 25             this._maxCount = maxCount;
 26             this._maxSize = maxSize;
 27         }
 28 
 29         /// <summary>
 30         /// 异步推送数据
 31         /// </summary>
 32         /// <param name="item"></param>
 33         /// <returns>数据成功加入待处理队列,返回true,数据达到队列的最大缓冲,数据不会进入队列,返回false</returns>
 34         public bool AsyncEnqueue(T item)
 35         {
 36             lock (this)
 37             {
 38                 if (this.queue.Count >= this._maxSize)
 39                     return false;
 40 
 41                 this.queue.Add(item);
 42                 this.Activate();
 43                 return true;
 44             }
 45         }
 46 
 47         protected T[] DoDequeue(List<T> queue)
 48         {
 49             if (queue.Count > this._maxCount)
 50             {
 51                 var ds = queue.Take(this._maxCount).ToArray();
 52                 queue.RemoveRange(0, this._maxCount);
 53                 return ds;
 54             }
 55             else
 56             {
 57                 var ds = queue.ToArray();
 58                 queue.Clear();
 59                 return ds;
 60             }
 61         }
 62 
 63         /// <summary>
 64         /// 实现此方法,批量执行处理时的方法
 65         /// </summary>
 66         /// <param name="items"></param>
 67         protected abstract void OnExecute(T[] items);
 68 
 69         private void Activate()
 70         {
 71             if (this._runing)
 72             {
 73                 return;
 74             }
 75 
 76             this._runing = true;
 77             ThreadPool.QueueUserWorkItem((obj) =>
 78             {
 79                 try
 80                 {
 81                     this._beforAction?.Invoke();
 82 
 83                     T[] items;
 84                     //管理线程
 85                     while (true)
 86                     {
 87                         lock (this)
 88                         {
 89                             if (queue.Count < 1)
 90                             {
 91                                 this._afterAction?.Invoke();
 92                                 this._runing = false;
 93                                 break;
 94                             }
 95 
 96                             items = this.DoDequeue(queue);
 97                         }
 98 
 99                         try
100                         {
101                             this.OnExecute(items);
102                         }
103                         catch (Exception ex)
104                         {
105                             //TODO:异常预警
106                             // Loger.Exception(ex.Message, ex);
107                         }
108                     }
109                 }
110                 catch (Exception ex)
111                 {
112                     //TODO:异常预警
113                     // Loger.Exception(ex.Message, ex);
114                 }
115             });
116         }
117 
118     }

 经测试,多线程单独写入DB,在开发环境,100/秒,但批量处理可达5000/秒。

转载于:https://www.cnblogs.com/likg/p/10458776.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值