- A+
所属分类:.NET技术
文章说明:
本文是基于盛派网络苏震巍老师的《微信公众号+小程序快速开发》课程笔记。
课程地址:
https://study.163.com/course/courseMain.htm?courseId=1004873017
本课项目地址:
https://github.com/wechatdeveloper/WechatVideoCourse
课程目标:
使用消息队列,执行有顺序的异步操作。也就是把蜂拥而至的请求,进行排队后,按照先进先执行的规则有顺序的执行。
队列图示:
微信中使用场景 :
大量用户向公众号发起消息请求,而微信的规则是需要在5S内响应返回给用户;
如果大量的并发请求出现,应用服务器可能产生堵塞,无法及时响应用户;
可变通的方法是:把所有的请求加入队列中,在队列中以客人消息的方式返回给用户,从而保证用户有良好的体验。
SDK SenparcMessageQueue 源码解读:
源码位置:https://github.com/Senparc/Senparc.CO2NET
把1个个的对象【SenparcMessageQueueItem】(Key标识唯一性),放到队列【MessageQueueDictionary】中, 然后逐个执行【OperateQueue】
【SenparcMessageQueueItem】:
1 /// <summary> 2 /// 队列项唯一标识 3 /// </summary> 4 public string Key { get; set; } 5 /// <summary> 6 /// 队列项目命中触发时执行的委托 7 /// </summary> 8 public Action Action { get; set; } 9 /// <summary> 10 /// 此实例对象的创建时间 11 /// </summary> 12 public DateTimeOffset AddTime { get; set; } 13 /// <summary> 14 /// 项目说明(主要用于调试) 15 /// </summary> 16 public string Description { get; set; } 17 18 /// <summary> 19 /// 初始化SenparcMessageQueue消息队列项 20 /// </summary> 21 /// <param name="key"></param> 22 /// <param name="action"></param> 23 /// <param name="description"></param> 24 public SenparcMessageQueueItem(string key, Action action, string description = null) 25 { 26 Key = key; 27 Action = action; 28 Description = description; 29 AddTime = SystemTime.Now; 30 }
【OperateQueue】获取对象 => 逐个执行 => 清除已执行的对象 => 获取下一个对象
1 /// <summary> 2 /// 操作队列 3 /// </summary> 4 public static void OperateQueue() 5 { 6 lock (FlushCacheLock) 7 { 8 var mq = new SenparcMessageQueue(); 9 var key = mq.GetCurrentKey(); //获取最新的Key 10 while (!string.IsNullOrEmpty(key)) 11 { 12 var mqItem = mq.GetItem(key); //获取任务项 13 mqItem.Action(); //执行 14 mq.Remove(key, out SenparcMessageQueueItem value); //清除 15 key = mq.GetCurrentKey(); //获取最新的Key 16 } 17 } 18 }
获取对象,是根据先进先出的原则:
1 /// <summary> 2 /// 获取当前等待执行的Key 3 /// </summary> 4 /// <returns></returns> 5 public string GetCurrentKey() 6 { 7 lock (MessageQueueSyncLock) 8 { 9 //不直接使用 Key 是因为 Key 的顺序是不确定的 10 var value = MessageQueueDictionary.Values.OrderBy(z=>z.AddTime).FirstOrDefault(); 11 if (value==null) 12 { 13 return null; 14 } 15 return value.Key; 16 } 17 }
队列执行效果: