目前市面上有诸多的产品实现队列功能,比如Redis、MemCache等...
其实c#中也有一个基础的集合类专门用来实现生产/消费模式 (生产模式还是建议使用Redis等产品)

下面是官方的一些资料和介绍:

BlockingCollection是一个线程安全集合类,可提供以下功能:

  • 实现制造者-使用者模式。

  • 通过多线程并发添加和获取项。

  • 可选最大容量。

  • 集合为空或已满时通过插入和移除操作进行阻塞。

  • 插入和移除“尝试”操作不发生阻塞,或在指定时间段内发生阻塞。

  • 封装实现 IProducerConsumerCollection 的任何集合类型

  • 使用取消标记执行取消操作。

  • 支持使用 foreach(在 Visual Basic 中,使用 For Each)的两种枚举:

    • 只读枚举。

    • 在枚举项时将项移除的枚举。

BlockingCollection 支持限制和阻塞。 限制意味着可以设置集合的最大容量。 限制在某些情况中很重要,因为它使你能够控制内存中的集合的最大大小,并可阻止制造线程移动到离使用线程前方太远的位置。

可以看到该类是完全线程安全的,因此用来做生产/消费是非常合适的

如下代码演示了该类在异步环境中很好的执行着生产和消费任务

using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Xunit; namespace AsyncLearning
{
public class TestProduceAndConsumer
{
/// <summary>
/// BlockingCollection是线程安全的集合类型,支持多线程同时读写
/// </summary>
private readonly BlockingCollection<string> _blockingQueue =
new BlockingCollection<string>(); private void Produce()
{
for (int i = 0; i < 10; i++) //限制生产1000次
{
var now = DateTime.Now.ToString(CultureInfo.InvariantCulture);
Debug.WriteLine($"第{i+1}次生产! {now}");
_blockingQueue.Add(now);
Thread.Sleep(1000); //特意减慢生产过程以至于不会太快。。。方便演示
} _blockingQueue.CompleteAdding(); //标记生产完成
} private void Consume()
{
int i = 1;
while (!_blockingQueue.IsCompleted)
{
var x = _blockingQueue.Take();
Debug.WriteLine($"第{i}次消费 {x}");
i++;
Thread.Sleep(2000); //故意减慢消费
}
} [Fact]
public void Test()
{ Task.WaitAll(Task.Run(() => { Produce(); }), Task.Run(() => { Consume(); }));
}
}
}

  

输出如下:

可见Demo很好的按照设定执行了代码逻辑,由于故意设定了不同的sleep时间,可以看到消费是晚于生产的,而消费全部完成后本Demo的任务全部结束

异步简析之BlockingCollection实现生产消费模式的更多相关文章

  1. zxing二维码扫描的流程简析(Android版)

    目前市面上二维码的扫描似乎用开源google的zxing比较多,接下去以2.2版本做一个简析吧,勿喷... 下载下来后定位两个文件夹,core和android,core是一些核心的库,android是 ...

  2. [转载] Thrift原理简析(JAVA)

    转载自http://shift-alt-ctrl.iteye.com/blog/1987416 Apache Thrift是一个跨语言的服务框架,本质上为RPC,同时具有序列化.发序列化机制:当我们开 ...

  3. SpringMVC源码情操陶冶-DispatcherServlet简析(二)

    承接前文SpringMVC源码情操陶冶-DispatcherServlet类简析(一),主要讲述初始化的操作,本文将简单介绍springmvc如何处理请求 DispatcherServlet#doDi ...

  4. 简析 __init__、__new__、__call__ 方法

    简析 __init__.__new__.__call__ 方法 任何事物都有一个从创建,被使用,再到消亡的过程,在程序语言面向对象编程模型中,对象也有相似的命运:创建.初始化.使 用.垃圾回收,不同的 ...

  5. Linux 目录结构学习与简析 Part2

    linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...

  6. Linux 磁盘分区方案简析

    Linux 磁盘分区方案简析 by:授客 QQ:1033553122   磁盘分区 任何硬盘在使用前都要进行分区.硬盘的分区有两种类型:主分区和扩展分区.一个硬盘上最多只能有4个主分区,其中一个主分区 ...

  7. 0002 - Spring MVC 拦截器源码简析:拦截器加载与执行

    1.概述 Spring MVC中的拦截器(Interceptor)类似于Servlet中的过滤器(Filter),它主要用于拦截用户请求并作相应的处理.例如通过拦截器可以进行权限验证.记录请求信息的日 ...

  8. 简析 Tomcat 、Nginx 与 Apache 的区别

    简析 Tomcat .Nginx 与 Apache 的区别 本文讲的是简析 Tomcat .Nginx 与Apache的区别, 经常在用 apache 和 tomcat 等这些服务器,可是总感觉还是不 ...

  9. Linux VFS机制简析(二)

    Linux VFS机制简析(二) 接上一篇Linux VFS机制简析(一),本篇继续介绍有关Address space和address operations.file和file operations. ...

随机推荐

  1. JS绑定带参数的事件总要执行一次方法,如何避免?

    类似这样:function aa(vote){alert(vote);}$(".btnn").bind("click",aa(1)});没有点击就开始执行了.怎 ...

  2. zabbix模板化监控

    zabbix模板化监控 1. 实验简述 在zabbix监控中,有很多组的概念,具体有以下几种: 1. 主机和主机组,相同类型/应用的主机,可以归属于同一个主机组 2. item和application ...

  3. UVA11825 黑客的攻击 Hackers' Crackdown 状压DP,二进制,子集枚举

    题目链接Click Here [题目描述] 假如你是一个黑客,侵入了一个有着\(n\)台计算机(编号为\(1.2.3....n\))的网络.一共有\(n\)种服务,每台计算机都运行着所有服务.对于每台 ...

  4. linux路由表

    Linux 内核的路由表通过 route 命令查看 Linux 内核的路由表: [root@VM_139_74_centos ~]# routeKernel IP routing tableDesti ...

  5. Docker配置镜像加速

    1.获取镜像地址 1.1.阿里云 打开网址:https://cr.console.aliyun.com/#/accelerator        注册.登录.设置密码        然后在页面上可以看 ...

  6. Docker实践之02-使用镜像及定制

    目录 一.获取镜像 二.使用镜像启动容器实例 三.列出镜像 四.删除本地镜像 五.定制镜像 通过commit命令定制镜像 通过Dockerfile定制镜像 docker build的工作原理 dock ...

  7. iTOP-4418/6818开发板用户使用手册内容有哪些

                    更多内容分享,请继续期待 iTOP-6818开发板与4418开发板共兼容同一底板: 核心板:::::: 尺寸:50mm*60mm 高度:核心板连接器组合高度1.5mm ...

  8. jmeter分布式测试教程和远程的代理机无法连接网络的问题解决方法

    一.Jmeter分布式执行原理: 1.Jmeter分布式测试时,选择其中一台作为控制机(Controller),其它机器做为代理机(Agent). 2.执行时,Controller会把脚本发送到每台A ...

  9. android TextView加载html 过滤所有标签,保留换行标签

    情景: TextView加载后端接口获取到的html富文本 遇到的问题: 客户端通过接口取到的数据如下: <p style="margin-top: 0px; margin-botto ...

  10. ARDUINO驱动LCD1602 (利用库函数)

    LCD 1602简介 工业字符型液晶,能够同时显示16x02即32个字符.(16列2行) 1602液晶也叫1602字符型液晶,它是一种专门用来显示字母.数字.符号等的点阵型液晶模块.它由若干个5X7或 ...