经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C# » 查看文章
C#神器"BlockingCollection"类实现C#神仙操作
来源:cnblogs  作者:百宝门园地  时间:2023/3/3 8:55:26  对本文有异议

前言

如果你想玩转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 操作符里面的数字是实现了可选最大容量,超出就线程阻塞了,程序一直卡在哪里

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

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

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

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

Task类简单介绍

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

Queue类简单介绍

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

接下来进入实际使用场景

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

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

  1. int count = 0 ;
  2. BlockingCollection<string> blockingCollection = new(1);
  3. //生产者
  4. Task.Factory.StartNew(() =>
  5. {
  6. while (true)
  7. {
  8. blockingCollection.Add("String: " + count);
  9. count++;
  10. if (count > 10)
  11. {
  12. blockingCollection.CompleteAdding();
  13. }
  14. }
  15. });
  16. //消费者
  17. Task.Factory.StartNew(() =>
  18. {
  19. foreach (var element in blockingCollection.GetConsumingEnumerable())
  20. {
  21. Thread.Sleep(1000);
  22. ("Work: " + element).Dump();//Dump 为工具Linq的功能
  23. }
  24. });

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

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

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

生产者/消费者输出结果

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

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

  1. //先进先出(FIFO)
  2. BlockingCollection<int> bc = new(new ConcurrentQueue<int>());
  3. bc.Add(1);
  4. bc.Add(2);
  5. bc.CompleteAdding();
  6. //先进后出(LIFO)
  7. BlockingCollection<int> bc2 = new(new ConcurrentStack<int>());
  8. bc2.Add(1);
  9. bc2.Add(2);
  10. bc2.CompleteAdding();
  11. bc.Take().Dump("bc1:");
  12. bc2.Take().Dump("bc2:");

队列输出结果

  1. bc 1
  2. bc2: 2

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

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

作者 => 百宝门瞿佑明

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

原文链接:https://www.cnblogs.com/baibaomen-org/p/17162795.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号