阻塞队列BlockCollection

本文最后更新于:2021年9月29日 下午

引言

阻塞队列的使用在开发过程中很常见,一般都是基于 生产者消费者问题 的应用。

案例:一个gps接收并入库的服务

基于如下场景:一秒钟会发送1000条,但我们只有一秒钟500条的处理速度,这个场景下会导致积压,所以不能用单线程来处理。应该考虑使用生产者消费者模式,开启多个消费者线程提升消费能力。

上述模式可行,但是又会引发出新的问题,如果还是存在消费速率差——即写入速度高于消费速度,那么队列会越来越大,直至撑爆内存。所以我们一般会使用一种叫阻塞队列的模式。固定队列的容量,当写入到达上限时阻塞,直到消费掉新的数据才能再次写入。

简单案例

如下是一个最简单的案例,一个线程生产数据,二个线程消费数据。

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
static void Main(string[] args)
{
var blockingCollection = new BlockingCollection<string>();
var producer = Task.Factory.StartNew(() =>
{
for (int count = 0; count < 10; count++)
{
blockingCollection.Add("value" + count);
Thread.Sleep(300);
}

blockingCollection.CompleteAdding();
});

var consumer1 = Task.Factory.StartNew(() =>
{
foreach (string value in blockingCollection.GetConsumingEnumerable())
{
Console.WriteLine("Worker 1: " + value);
}
});

var consumer2 = Task.Factory.StartNew(() =>
{
foreach (string value in blockingCollection.GetConsumingEnumerable())
{
Console.WriteLine("Worker 2: " + value);
}
});

Task.WaitAll(producer, consumer1, consumer2);
}

参考

https://www.cnblogs.com/dxy1982/p/3640210.html

https://blog.csdn.net/ma_jiang/article/details/54561684

BlockingCollection


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!