ConcurrentQueue和BlockingCollection的区别
区别
1. 阻塞行为(最核心区别)
- 
ConcurrentQueue<T>:无阻塞机制它仅保证线程安全的队列操作,但不提供“阻塞”功能。
- 
当队列为空时,调用
Dequeue()会直接抛出InvalidOperationException;
必须使用TryDequeue(out T)方法(返回bool表示是否成功),若失败需手动处理(如线程休眠、循环重试)。 - 
当队列非空时,入队(
Enqueue(T))和出队(TryDequeue)操作均为非阻塞,直接执行。 
 - 
 - 
BlockingCollection<T>:原生支持阻塞操作它的核心价值在于内置阻塞逻辑,无需手动处理线程等待:
- 
出队阻塞:调用
Take()方法时,若集合为空,当前线程会阻塞,直到有元素可用(或集合被标记为“完成”)。 - 
入队阻塞:若为集合设置了容量上限(如
new BlockingCollection<T>(boundedCapacity: 100)),当元素数量达到上限时,调用Add(T)会阻塞,直到有元素被取出(腾出空间)。 - 
此外,还提供
TryTake(out T, TimeSpan)和TryAdd(T, TimeSpan)方法,支持“超时阻塞”(超过指定时间未成功则返回false),避免无限阻塞。 
 - 
 
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
using System.Collections.Concurrent;
using System.Threading.Tasks;
class ConcurrentQueueExample
{
    private static readonly ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
    private static volatile bool isProducingComplete = false;
    static async Task Main()
    {
        // 启动生产者任务
        var producerTask = Task.Run(() => Produce());
        // 启动消费者任务
        var consumerTask = Task.Run(() => Consume());
        // 等待生产者完成
        await producerTask;
        isProducingComplete = true; // 标记生产完成
        // 等待消费者完成
        await consumerTask;
        Console.WriteLine("所有任务已完成");
    }
    static void Produce()
    {
        for (int i = 0; i < 10; i++)
        {
            queue.Enqueue(i);
            Console.WriteLine($"生产者添加: {i}");
            Thread.Sleep(100); // 模拟生产耗时
        }
    }
    static void Consume()
    {
        // ♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈
        while (!isProducingComplete || queue.Count > 0)
        {
            // ♈♈♈♈♈♈♈♈♈♈♈♈
            if (queue.TryDequeue(out int item))
            {
                Console.WriteLine($"消费者处理: {item}");
                Thread.Sleep(200); // 模拟消费耗时
            }
            else
            {
                // 队列为空时,短暂休眠避免CPU空转
                Thread.Sleep(50);
            }
        }
    }
}
BlockingCollection<int> collection = new BlockingCollection<int>();
using System.Collections.Concurrent;
using System.Threading.Tasks;
class BlockingCollectionExample
{
    private static readonly BlockingCollection<int> collection = new BlockingCollection<int>();
    static async Task Main()
    {
        // 启动生产者任务
        var producerTask = Task.Run(() => Produce());
        // 启动消费者任务
        var consumerTask = Task.Run(() => Consume());
        // 等待生产者完成
        await producerTask;
        ♈♈♈♈♈♈♈♈♈♈♈
        collection.CompleteAdding(); // 标记生产完成
        // 等待消费者完成
        await consumerTask;
        Console.WriteLine("所有任务已完成");
    }
    static void Produce()
    {
        for (int i = 0; i < 10; i++)
        {
            collection.Add(i);
            Console.WriteLine($"生产者添加: {i}");
            Thread.Sleep(100); // 模拟生产耗时
        }
    }
    static void Consume()
    {
        // ♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈♈
        // 使用 GetConsumingEnumerable 自动处理阻塞和完成
        foreach (var item in collection.GetConsumingEnumerable())
        {
            Console.WriteLine($"消费者处理: {item}");
            Thread.Sleep(200); // 模拟消费耗时
        }
    }
}
                    
                
                
                
            
        
浙公网安备 33010602011771号