C#神器“BlockingCollection“类实现C#神仙操作

本文介绍了C#中的BlockingCollection类,它是线程安全的集合,用于实现生产者/消费者模式。通过示例代码展示了如何利用BlockingCollection进行多线程并发添加和获取元素,以及如何设置最大容量和使用取消标记。同时,文章还提到了Task类作为线程管理工具和Queue类作为FIFO数据结构在并发编程中的应用。
摘要由CSDN通过智能技术生成

前言

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

BlockingCollection简单介绍

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

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

  1. 实现制造者-使用者模式

  1. 通过多线程并发添加和获取项

  1. 可选最大容量

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

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

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

  1. 使用取消标记执行取消操作

  1. 支持使用 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. 多线程并发添加和获取项

  1. 生产者和消费者模式

  1. 使用取消标记执行取消操作(让生产者知道我们已经不需要你工作了)

生产者/消费者输出结果

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也可以实现队列的功能
以上就是本期的全部内容啦谢谢大家看到这里
作者 => 百宝门瞿佑明

原文地址:C#神器"BlockingCollection"类实现C#神仙操作 - 百宝门的博客 (baibaomen.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值