第一步:定义队列服务接口

  1. public interface ISimpleQueueServer
  2. {
  3. /// <summary>
  4. /// 添加队列消息
  5. /// </summary>
  6. /// <param name="message">消息</param>
  7. /// <param name="clientName">客户端名称</param>
  8. /// <returns></returns>
  9. string Add(string message, string clientName);
  10. }

第二步:添加队列服务接口的实现

  1. public class SimpleQueueServer : ISimpleQueueServer
  2. {
  3. /// <summary>
  4. /// 队列
  5. /// </summary>
  6. private static ConcurrentQueue<string> _queue = new ConcurrentQueue<string>();
  7.  
  8. /// <summary>
  9. /// 日志
  10. /// </summary>
  11. private static ILogger _log;
  12.  
  13. /// <summary>
  14. /// 后台任务
  15. /// </summary>
  16. private static Task _task;
  17.  
  18. /// <summary>
  19. /// 连续获取队列为空的次数
  20. /// </summary>
  21. private int EmptyRepeatCount = 0;
  22.  
  23. /// <summary>
  24. /// 属性,后台任务
  25. /// </summary>
  26. private Task MyTask
  27. {
  28. get
  29. {
  30. if (_task == null)
  31. {
  32. _task = new Task(MessageHandler);
  33. }
  34. return _task;
  35. }
  36. }
  37.  
  38. /// <summary>
  39. /// 构造函数
  40. /// </summary>
  41. /// <param name="factory"></param>
  42. public SimpleQueueServer(ILoggerFactory factory)
  43. {
  44. if (_log == null)
  45. {
  46. _log = factory.CreateLogger("SimpleQueueServer");
  47. }
  48.  
  49. MyTask.Start();
  50. }
  51.  
  52. /// <summary>
  53. /// 添加消息到队列
  54. /// </summary>
  55. /// <param name="message">消息</param>
  56. /// <param name="clientName">发送的客户端名称</param>
  57. /// <returns></returns>
  58. public string Add(string message, string clientName = "")
  59. {
  60. try
  61. {
  62. string prefix = string.IsNullOrWhiteSpace(clientName) ? "" : $"【{clientName}】";
  63. _queue.Enqueue($"{prefix}{message}");
  64. return "OK";
  65. }
  66. catch (Exception ex)
  67. {
  68. _log.LogError(ex, "向队列添加信息失败");
  69. return ex.Message;
  70. }
  71. }
  72.  
  73. /// <summary>
  74. /// 队列中要实现的任务
  75. /// </summary>
  76. /// <param name="threadName">线程名称,如果多</param>
  77. /// <returns></returns>
  78. private Action MessageHandler => () =>
  79. {
  80. while (true)
  81. {
  82. try
  83. {
  84. if (_queue.IsEmpty)
  85. {
  86. _log.LogDebug($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 队列为空");
  87. Thread.Sleep(3000);
  88. }
  89. else
  90. {
  91. if (_queue.TryDequeue(out string result))
  92. {
  93. _log.LogDebug($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 获取到数据:{result}");
  94. }
  95. else
  96. {
  97. _log.LogDebug($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} 尝试从队列获取消息失败");
  98. }
  99. Thread.Sleep(500);
  100. }
  101. }
  102. catch (Exception ex)
  103. {
  104. _log.LogError(ex, "系统错误");
  105. }
  106. }
  107. };
  108. }

第三步:在startup中注册服务,这里稍稍装个x,定义一个IServiceCollection扩展,让代码看起来x格稍微高点

  1. public static class ServiceCollectionExtension
  2. {
  3. public static void AddSimpleQueueServer(this IServiceCollection services)
  4. {
  5. services.AddSingleton<ISimpleQueueServer, SimpleQueueServer>((provider) =>
  6. {
  7. return new SimpleQueueServer(provider.GetService<ILoggerFactory>());
  8. });
  9. }
    }

第四步:在startup的ConfigureServices中添加服务

  1. services.AddSimpleQueueServer();

第五步:修改appsettings.Development.json文件

  1. {
  2. "Logging": {
  3. "LogLevel": {
  4. "Default": "Debug",
  5. "System": "Warning",
  6. "Microsoft": "Warning"
  7. }
  8. }
  9. }

修改System和Microsoft的日志级别,防止调试时队列显示的消息淹没在无穷无尽的info中。

=======无聊的分割线======

新建一个QueueController

  1. namespace AspnetCoreMvcStudy.Controllers
  2. {
  3. public class QueueController : Controller
  4. {
  5. private ISimpleQueueServer _server;
  6.  
  7. public QueueController(ISimpleQueueServer server)
  8. {
  9. _server = server;
  10. }
  11.  
  12. public IActionResult Index()
  13. {
  14. return View();
  15. }
  16.  
  17. [HttpPost]
  18. public JsonResult Send(string msg, string client)
  19. {
  20. for (int i = 0; i < 100; i++)
  21. {
  22. _server.Add($"{msg}-{i}", client);
  23. }
  24. return Json(new { Code = 200 });
  25. }
  26. }
  27. }

创建视图 Index.cshtml

  1. @{
  2. ViewData["Title"] = "Index";
  3. }
  4.  
  5. <h2>队列测试</h2>
  6.  
  7. <form id="form1" onsubmit="return false;">
  8. <div class="form-group">
  9. <label for="message">客户端名称</label>
  10. <input type="text" id="client" value="" />
  11. <label for="message">发送内容</label>
  12. <input type="text" id="message" value="" />
  13. <hr />
  14. <button id="btnSubmit" class="btn btn-success">发送</button>
  15. <span class="text-danger" id="info"></span>
  16. </div>
  17. </form>
  18.  
  19. @section scripts
  20. {
  21. <script>
  22. $('#btnSubmit').on('click', function () {
  23. var that = $(this);
  24. that.attr('disabled', 'disabled');
  25. $.post('/Queue/Send', { msg: $('#message').val(), client: $('#client').val() }, function (response) {
  26. if (response.code == 200) {
  27. $('#info').text('发送成功');
  28. } else {
  29. $('#info').text(response.message);
  30. }
  31. that.removeAttr('disabled');
  32. });
  33. });
  34. </script>
  35. }

运行程序,开整

【aspnetcore】用ConcurrentQueue实现一个简单的队列系统的更多相关文章

  1. 《Linux内核分析》第三周 构建一个简单的Linux系统MenuOS

    [刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK THREE ...

  2. Linux第三周学习总结——构造一个简单的Linux系统MenuOS

    第三周学习总结--构造一个简单的Linux系统MenuOS 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/ ...

  3. Python高级编程之生成器(Generator)与coroutine(四):一个简单的多任务系统

    啊,终于要把这一个系列写完整了,好高兴啊 在前面的三篇文章中介绍了Python的Python的Generator和coroutine(协程)相关的编程技术,接下来这篇文章会用Python的corout ...

  4. Linux内核设计第三周——构造一个简单的Linux系统

    Linux内核设计第三周 ——构造一个简单的Linux系统 一.知识点总结 计算机三个法宝: 存储程序计算机 函数调用堆栈 中断 操作系统两把宝剑: 中断上下文的切换 进程上下文的切换 linux内核 ...

  5. 第三节 构造一个简单的Linux系统MenuOS——20135203齐岳

    第三节 构造一个简单的Linux系统MenuOS By 20135203齐岳 Linux内核源代码 arch/ 支持不同cpu的源代码 Documentations/ 文档存储 init/ 内核启动相 ...

  6. Linux内核分析第三周学习总结:构造一个简单的Linux系统MenuOS

    韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.Linux内 ...

  7. 一个简单的CS系统打包过程图文版

    一个简单的CS系统打包过程图文版 1.     打包内容 1.1.  此次打包的要求和特点 主工程是一个CS系统: 此CS系统运行的先决条件是要有.Net Framework 3.5: 主工程安装完成 ...

  8. Linux下一个简单的日志系统的设计及其C代码实现

    1.概述 在大型软件系统中,为了监测软件运行状况及排查软件故障,一般都会要求软件程序在运行的过程中产生日志文件.在日志文件中存放程序流程中的一些重要信息, 包括:变量名称及其值.消息结构定义.函数返回 ...

  9. python制作一个简单的中奖系统

    注释: 展示图下的代码,我是用pycharm写的,是python解释器中的一种,本课没不同解释器的要求,可根据自己喜欢的解释器编写. 步骤: 本期给大家带来的是,一个简单的中奖系统,首先打开自己电脑上 ...

随机推荐

  1. html5--5-16 综合实例绘制饼图

    html5--5-16 综合实例绘制饼图 实例 <!doctype html> <html> <head> <meta charset="utf-8 ...

  2. Mongodb GridFS——适合大小超过16MB的文件

    一.概述 GridFS是基于mongodb存储引擎是实现的“分布式文件系统”,底层基于mongodb存储机制,和其他本地文件系统相比,它具备大数据存储的多个优点.GridFS适合存储超过16MB的大型 ...

  3. UEBA——通过用户画像识别安全威胁

    UEBA and Machine Learning - Download Free Guide for CISOs‎ Adinfo.niara.com/UEBA/Guide-For-CISOs‎ Le ...

  4. hdu-5670 Machine(水题附上java代码)

    题目链接: Machine  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 65536/65536 K (Java/Others) 问题描 ...

  5. JavaScript 日期处理类库 moment

    可以自定义自己需要的时间格式,中文文档如下: http://momentjs.cn/ http://momentjs.cn/docs/

  6. 使用Axis2创建Web Service

    Axis2是新一代Web Service开发工具,目前最新版本是1.5.本文主要介绍如何用Axis2创建Web Service. 首先下载二进制包和war包,将war包复制到Tomcat的webapp ...

  7. HBase之四--(3):hbasehbase分页查询

    为了广大技术爱好者学习netty,在这里帮新浪微博@nettying宣传下他出版的新书 <netty权威指南>@nettying兄在华为NIO实践多年,这本书是他的技术和经验的一个结晶.N ...

  8. bzoj2117

    动态电分治+二分 肯定要枚举所有点对,那么我们建出点分树降低树高,然后每个点存下点分树中所有子树到这个点的距离,然后二分+lower_bound就行了. #include<bits/stdc++ ...

  9. POJ-3629

    Card Stacking Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3927   Accepted: 1541 Des ...

  10. Linux下共享库嵌套依赖问题 (转载)

    转自:http://my.oschina.net/moooofly/blog/506466 问题场景: 动态库 librabbitmq_r.so 内部依赖动态库 libevent_core.so 和 ...