前言

如果你想玩转C# 里面多线程,工厂模式,生产者/消费者,队列等高级操作,就可以和我一起探索这个强大的线程安全提供阻塞和限制功能的C#神器类

BlockingCollection简单介绍

微软介绍地址:https://learn.microsoft.com/zh-cn/dotnet/standard/collections/thread-safe/blockingcollection-overview

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

  1. 实现制造者-使用者模式
  2. 通过多线程并发添加和获取项
  3. 可选最大容量
  4. 集合为空或已满时通过插入和移除操作进行阻塞
  5. 插入和移除“尝试”操作不发生阻塞,或在指定时间段内发生阻塞
  6. 封装实现 IProducerConsumerCollection 的任何集合类型
  7. 使用取消标记执行取消操作
  8. 支持使用 foreach(在 Visual Basic 中,使用 For Each)的两种枚举:1. 只读枚举,2. 在枚举项时将项移除的枚举

起手式

BlockingCollection blockingCollection = new(1);

  • new 操作符里面的数字是实现了可选最大容量,超出就线程阻塞了,程序一直卡在哪里

先来个开胃菜 => 三句代码实现线程阻塞

BlockingCollection<int> blockingCollection = new(1);
blockingCollection.Add(1);
blockingCollection.Add(2);

说明:因为限制队列只能插入一条,第一条没有消费掉,所以一直卡在插入第二条程序不会往下继续运行实现了集合为空或已满时通过插入和移除操作进行阻塞

正式开始前先分享一些多线程的知识点

Task类简单介绍

Task 表面上是Thread但却是对ThreadPool的封装,控制和扩展性很强,对线程的延续,阻塞,取消,超时,比传统的Thread和ThreadPool强

Queue类简单介绍

队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队

接下来进入实际使用场景

场景一: 生产者=> 消费者

建议代码还是要动手实现一下,不然体会不到一边生产数据,同时还能取数据的神仙操作

int count = 0 ;
BlockingCollection<string> blockingCollection = new(1);
//生产者
Task.Factory.StartNew(() =>
{
while (true)
{
blockingCollection.Add("String: " + count);
count++;
if (count > 10)
{
blockingCollection.CompleteAdding();
}
}
}); //消费者
Task.Factory.StartNew(() =>
{
foreach (var element in blockingCollection.GetConsumingEnumerable())
{
Thread.Sleep(1000);
("Work: " + element).Dump();//Dump 为工具Linq的功能
}
});

上面的代码中这个方法GetConsumingEnumerable很重要,它可以在BlockingCollection集合有数据的时候取数据,没有的话停止取,可以达到监测的效果

这个案例实现了如下功能:

  1. 多线程并发添加和获取项
  2. 生产者和消费者模式
  3. 使用取消标记执行取消操作(让生产者知道我们已经不需要你工作了)

生产者/消费者输出结果

Work: String: 0
Work: String: 1
Work: String: 2
Work: String: 3
Work: String: 4
Work: String: 5
Work: String: 6
Work: String: 7
Work: String: 8
Work: String: 9
Work: String: 10

场景二: 实现队列FIFO(先进先出),LIFO(先进后出)

 //先进先出(FIFO)
BlockingCollection<int> bc = new(new ConcurrentQueue<int>());
bc.Add(1);
bc.Add(2);
bc.CompleteAdding(); //先进后出(LIFO)
BlockingCollection<int> bc2 = new(new ConcurrentStack<int>());
bc2.Add(1);
bc2.Add(2);
bc2.CompleteAdding(); bc.Take().Dump("bc1:");
bc2.Take().Dump("bc2:");

队列输出结果

bc :1
bc2: 2

这个简单的案例是想介绍一下其实:BlockingCollection也可以实现队列的功能

以上就是本期的全部内容啦谢谢大家看到这里

作者 => 百宝门瞿佑明

原文地址:https://blog.baibaomen.com/c神器blockingcollection类实现c神仙操作/

C#神器"BlockingCollection"类实现C#神仙操作的更多相关文章

  1. 基于MVC4+EasyUI的Web开发框架形成之旅--基类控制器CRUD的操作

    在上一篇随笔中,我对Web开发框架的总体界面进行了介绍,其中并提到了我的<Web开发框架>的控制器的设计关系,Web开发框架沿用了我的<Winform开发框架>的很多架构设计思 ...

  2. android SQLite使用SQLiteOpenHelper类对数据库进行操作

    android SQLite使用SQLiteOpenHelper类对数据库进行操作 原文: http://byandby.iteye.com/blog/835580

  3. Java通过代理类实现数据库DAO操作

    下面的所有代码示例都取自李兴华的<Java Web开发实战经典>的随书源码,因为觉得设计得很好,所以将代码摘录下来作成笔记. 首先,我们在一个java文件中定义要存储的结构类型: impo ...

  4. 关于“类不能支持Automation操作”错误的解决方法

    一段程序IE上老是提示“类不支持Automation操作”的错误,IE6.7.8都一样,但是Firefox可以,后来网上找到如下解决方法: 重新注册下以下文件,问题便解决了:msscript.ocxd ...

  5. String 类上的常用操作

    java 中String 类上的常用操作: 首先创建对象  String line = new String("String demo"); String line2 = new ...

  6. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  7. 基于MVC4+EasyUI的Web开发框架形成之旅(6)--基类控制器CRUD的操作

    在上一篇随笔中,我对Web开发框架的总体界面进行了介绍,其中并提到了我的<Web开发框架>的控制器的设计关系,Web开发框架沿用了我的<Winform开发框架>的很多架构设计思 ...

  8. Java1.8 JDK源码中,对两个类进行 按位与 操作是什么意思

    Java容器类库中的Map接口(java\util\Map.java)中有一个Entry接口(java\util\Map.java),其中有几个接口方法用到了类和类的按位与操作,即类和类之间有 &am ...

  9. VS2010/MFC编程入门之四十五(MFC常用类:CFile文件操作类)

    上一节中鸡啄米讲了定时器Timer的用法,本节介绍下文件操作类CFile类的使用. CFile类概述 如果你学过C语言,应该知道文件操作使用的是文件指针,通过文件指针实现对它指向的文件的各种操作.这些 ...

  10. opencv学习笔记——FileStorage类的数据存取操作

    OpenCV的许多应用都需要使用数据的存储于读取,例如经过3D校准后的相机,需要存储校准结果矩阵,以方便下次调用该数据:基于机器学习的应用,同样需要将学习得到的参数保存等.OpenCV通过XML/YA ...

随机推荐

  1. 【Java技术】String类的使用

    属于引用类型,在java.lang包下,类似的还有Integer.Character.Boolean.Math 常用方法: char charAt(int index)返回 char指定索引处的值. ...

  2. 当我们说大数据Hadoop,究竟在说什么?

    前言 提到大数据,大抵逃不过两个问题,一个是海量的数据该如何存储,另外一个就是那么多数据该如何进行查询计算呢.好在这些问题前人都有了解决方案,而Hadoop就是其中的佼佼者,是目前市面上最流行的一个大 ...

  3. 分布式计算MapReduce究竟是怎么一回事?

    前言 如果要对文件中的内容进行统计,大家觉得怎么做呢?一般的思路都是将不同地方的文件数据读取到内存中,最后集中进行统计.如果数据量少还好,但是面对海量数据.大数据的场景这样真的合适吗?不合适的话,那有 ...

  4. jmeter 之 JSON 断言

    1.JSON 断言所在位置:断言->JSON 断言 2.JSON断言中的字段解析 Assert JSON Path exists:json 表达式,判断所字段是否存在,存在则为True, 否则为 ...

  5. 分享一个自己在用的.net 中mysql事务控制类(支持多条sql,参数化,自定义判断条件,错误点返回等)

    1)首先看下事务控制器. using MySql.Data.MySqlClient; using System; using System.Collections.Generic; using Sys ...

  6. [python] 基于chardet识别字符编码

    对于人类能够识别的字符,计算机会根据某一对应关系将其转换为二进制形式进行保存.这个对应关系就是字符编码表,即什么样的字符对应什么样的二进制编码.这种字符编码表往往是多种多样的,因此,如果我们想要将一个 ...

  7. [OpenCV实战]44 使用OpenCV进行图像超分放大

    图像超分辨率(Image Super Resolution)是指从低分辨率图像或图像序列得到高分辨率图像.图像超分辨率是计算机视觉领域中一个非常重要的研究问题,广泛应用于医学图像分析.生物识别.视频监 ...

  8. Fast RCNN论文阅读笔记

    1.Introduction 1.1 RCNN 和SPPnet RCNN有几个显著的问题:1.训练的时候是多阶段的训练,分别分三个阶段训练卷积层.SVM.边框回归矩阵.2.训练很耗时.3.目标定位非常 ...

  9. 痞子衡嵌入式:MCUBootUtility v4.0发布,开始支持MCX啦

    -- 痞子衡维护的 NXP-MCUBootUtility 工具距离上一个大版本(v3.5.0)发布过去 9 个月了,这一次痞子衡为大家带来了版本升级 v4.0.0,这个版本主要有两个重要更新需要跟大家 ...

  10. Java基础篇——多线程

    创建线程的三种方式 1.继承Thread类 2.实现Runnable接口 3.实现Callable接口 继承Thread类 public Test extends Thread{ public voi ...