异步简析之BlockingCollection实现生产消费模式

目前市面上有诸多的产品实现队列功能,比如Redis、MemCache等... 其实c#中也有一个基础的集合类专门用来实现生产/消费模式 (生产模式还是建议使用Redis等产品) 下面是官方的一些资料和介绍: BlockingCollection 是一个线程安全集合类,可提供以下功能: 实现制造者-使用者模式。 通过多线程并发添加和获取项。 可选最大容量。 集合为空或已满时通过插入和移除操作进行阻塞。 插入和移除“尝试”操作不发生阻塞,或在指定时间段内发生阻塞。 封装实现 IProducerConsumerCollection 的任何集合类型 使用取消标记执行取消操作。 支持使用 foreach(在 Visual Basic 中,使用 For Each)的两种枚举: 只读枚举。 在枚举项时将项移除的枚举。 BlockingCollection 支持限制和阻塞。 限制意味着可以设置集合的最大容量。 限制在某些情况中很重要,因为它使你能够控制内存中的集合的最大大小,并可阻止制造线程移动到离使用线程前方太远的位置。 可以看到该类是完全线程安全的,因此用来做生产/消费是非常合适的 如下代码演示了该类在异步环境中很好的执行着生产和消费任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 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 { /// /// BlockingCollection是线程安全的集合类型,支持多线程同时读写 /// private readonly BlockingCollection _blockingQueue = new BlockingCollection(); 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的任务全部结束https://www.cnblogs.com/linkanyway/p/produce-consume-task-async.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信