前言

如果你想玩转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. C#从实习到搬砖

    日常唠唠 没事就聊聊我在c#上踩过的那些坑,和一些笔记 少点比较,多些谦虚 会者不难 原博:轩先生大冒险 2022.4.19 datagridview 修改表头 dataGridView1.Colum ...

  2. LeetCode HOT 100:下一个排列

    题目:31. 下一个排列 题目描述: 本题是给你一个整数数组,返回该数组的下一个线性顺序排列. 举个例子:给你一个[1, 2, 3]的数组,他的线性排列顺序从小到大依次为[1, 3, 2],[2, 1 ...

  3. 服务器迁移遇到的bug

    目前有个客户做了个下单系统,系统运行了太多的扩展了,但是又没有文档,我就想着能不能把服务器打包成镜像,然后用新服务直接使用?? 事实是完全OK的.服务器用的阿里云. 但是遇到一个bug,我目前还没解决 ...

  4. 高可用系列文章之三 - NGINX 高可用实施方案

    前文链接 高可用系列文章之一 - 概述 - 东风微鸣技术博客 (ewhisper.cn) 高可用系列文章之二 - 传统分层架构技术方案 - 东风微鸣技术博客 (ewhisper.cn) 四 NGINX ...

  5. [OpenCV实战]18 Opencv中的单应性矩阵Homography

    目录 1 介绍 1.1 什么是Homography 1.2 使用Homography进行图像对齐 1.3 Homography的应用-全景拼接 2 Homography的计算 3 总结 4 参考 &l ...

  6. [OpenCV实战]7 使用YOLOv3和OpenCV进行基于深度学习的目标检测

    目录 1 YOLO介绍 1.1 YOLOv3原理 1.2 为什么要将OpenCV用于YOLO? 1.3 在Darknet和OpenCV上对YOLOv3进行速度测试 2 使用YOLOv3进行对象检测(C ...

  7. ArcGIS工具 - 按字段分割图层

    天下大势,合久必分,分久必合.合并.分割在GIS数据处理和管理中也十分常见,例如按行政区划名称导出多个区县行政图层.按地类名称导出多个地类图层. 功能说明 其实,在ArcGIS中除了按属性导出外,最接 ...

  8. python31 网络并发编程方法

    同步与异步 用来表达任务的提交方式 同步 提交完任务之后原地等待任务的返回结果 期间不做任何事 异步 提交完任务之后不原地等待任务的返回结果 直接去做其他事 有结果自动通知 阻塞与非阻塞 用来表达任务 ...

  9. [C#]简单的理解委托和事件

    委托 在C++中可以利用"函数指针"将对方法的引用作为实参传递给另一个方法,而C#中可以利用委托提供相同的功能. 委托-内部机制 但是委托实际上是一个特殊的类.委托必须直接或间接的 ...

  10. [C++标准模板库:自修教程与参考手册]关于auto_ptr

    什么是auto_ptr指针 auto_ptr是这样一种指针:它是"它所指的对象"的拥有者,所以,当身为对象拥有者的auto_ptr指针被摧毁时,该对象也会被摧毁,auto_ptr要 ...