BlockingCollection
和ConcurrentBag
是C#中用于多线程环境的集合类。BlockingCollection
基于阻塞队列,适用于生产者-消费者模型,提供了对任务的安全访问。ConcurrentBag
是一个无序的、线程安全的集合,适用于多线程环境下无序的元素插入和删除。
BlockingCollection:
Add(item)
:向集合中添加元素,如果集合已满则阻塞。Take()
:从集合中取出元素,如果集合为空则阻塞。ConcurrentBag:
Add(item)
:向集合中添加元素,支持并发添加。TryTake(out item)
:尝试从集合中取出元素。BlockingCollection:
BlockingCollection
对象。Add
方法添加元素。Take
方法取出元素。ConcurrentBag:
ConcurrentBag
对象。Add
方法添加元素。TryTake
方法尝试取出元素。using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// 使用BlockingCollection
BlockingCollection<int> blockingCollection = new BlockingCollection<int>(boundedCapacity: 5);
// 生产者
Task.Run(() =>
{
for (int i = 0; i < 10; i++)
{
blockingCollection.Add(i);
Console.WriteLine($"生产者添加: {i}");
Thread.Sleep(100);
}
blockingCollection.CompleteAdding();
});
// 消费者
Task.Run(() =>
{
foreach (var item in blockingCollection.GetConsumingEnumerable())
{
Console.WriteLine($"消费者取出: {item}");
Thread.Sleep(200);
}
});
// 使用ConcurrentBag
ConcurrentBag<int> concurrentBag = new ConcurrentBag<int>();
// 多线程并发添加元素
Parallel.For(0, 10, i =>
{
concurrentBag.Add(i);
Console.WriteLine($"添加元素: {i}");
Thread.Sleep(100);
});
// 多线程并发尝试取出元素
Parallel.For(0, 10, i =>
{
if (concurrentBag.TryTake(out var item))
{
Console.WriteLine($"尝试取出元素: {item}");
}
Thread.Sleep(200);
});
}
}
BlockingCollection
适用于需要阻塞等待的生产者-消费者模型,提供了高度的灵活性。ConcurrentBag
适用于多线程环境下无序的元素插入和删除场景,提供了更简单的接口。在选择时需根据具体场景的需求来决定使用哪个集合类。