BlockingCollection<T> 类 粗略学习经验
BlockingCollection 类 实现 IProducerConsumerCollection 的线程安全集合提供阻塞和限制功能。
我的理解是 生产者向集合内按照队列的形式添加元素,读取按照队列的方式读取,当集合中没有了元素,读取就会阻塞线程(GetConsumingEnumerable())
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace BlockingCollectionDemo
{
class Program
{
static void Main(string[] args)
{
Parallel.Invoke(Test.AddItem, Test.Read, Test.IsCompleted);
Console.WriteLine("Hello World!");
}
}
public class Test
{
private readonly static BlockingCollection<int> cols = new BlockingCollection<int>();
public static void AddItem()
{
for (var i = 0; i < 10; i++)
{
cols.Add(i);
Console.WriteLine("write value:{0}", i);
Thread.Sleep(1000);
}
cols.CompleteAdding(); // 不执行该方法,会造成 GetConsumingEnumerable() 阻塞
var iscompleted = cols.IsAddingCompleted;
Console.WriteLine("add completed value:{0}", iscompleted);
var isscompleted = cols.IsCompleted;
Console.WriteLine("a completed value:{0}", isscompleted);
}
public static void Read()
{
foreach (var item in cols.GetConsumingEnumerable())
{
var iscompleted = cols.IsCompleted;
Console.WriteLine("b completed value:{0}", iscompleted);
Console.WriteLine("read value:{0}", item);
Thread.Sleep(1500);
}
Console.WriteLine("read done.");
}
public static void IsCompleted()
{
var iscompleted = false;
while (!iscompleted)
{
iscompleted = cols.IsCompleted;
Console.WriteLine("completed value:{0}", iscompleted);
Thread.Sleep(1000);
}
}
}
}