在C#多线程编程中,如何安全地在线程之间传递数据是一个常见且关键的问题。.NET 提供了 BlockingCollection<T> 类,它是一个线程安全的集合,特别适用于 生产者-消费者模式。本文将带你从零开始,深入浅出地学习 C# BlockingCollection 的基本用法、核心特性以及实际应用场景。

BlockingCollection<T> 是 .NET Framework 4.0 引入的一个线程安全集合类,位于 System.Collections.Concurrent 命名空间。它本质上是对 IProducerConsumerCollection<T>(如 ConcurrentQueue<T>、ConcurrentStack<T> 等)的封装,并提供了阻塞和限界(bounded capacity)功能。
主要特点包括:
CompleteAdding() 方法通知消费者不再有新数据。下面是一个简单的 生产者-消费者 示例,展示如何使用 BlockingCollection<int>。
using System;using System.Collections.Concurrent;using System.Threading;using System.Threading.Tasks;class Program{ static void Main() { // 创建一个无容量上限的 BlockingCollection,默认底层使用 ConcurrentQueue var blockingCollection = new BlockingCollection<int>(); // 启动生产者任务 Task producer = Task.Run(() => { for (int i = 1; i <= 5; i++) { blockingCollection.Add(i); Console.WriteLine($"生产者:添加了 {i}"); Thread.Sleep(500); // 模拟耗时操作 } // 标记添加完成 blockingCollection.CompleteAdding(); Console.WriteLine("生产者:完成添加。"); }); // 启动消费者任务 Task consumer = Task.Run(() => { // 使用 GetConsumingEnumerable() 安全遍历,直到 CompleteAdding 被调用 foreach (int item in blockingCollection.GetConsumingEnumerable()) { Console.WriteLine($"消费者:处理了 {item}"); Thread.Sleep(800); // 模拟处理时间 } Console.WriteLine("消费者:处理完毕。"); }); // 等待两个任务完成 Task.WaitAll(producer, consumer); Console.WriteLine("程序结束。"); }}运行上述代码,你会看到生产者逐个添加数字,消费者逐个处理,即使两者速度不同,也能协调工作。这正是 多线程安全集合 的强大之处。
有时我们希望限制集合的最大容量,防止内存溢出。可以通过构造函数指定容量上限:
// 创建一个最多容纳 3 个元素的 BlockingCollectionvar boundedCollection = new BlockingCollection<string>(3);// 如果尝试添加第4个元素,Add() 会阻塞,直到有元素被取走boundedCollection.Add("A");boundedCollection.Add("B");boundedCollection.Add("C");// 此时再 Add 会等待boundedCollection.Add("D"); // 阻塞,直到消费者取走一个| 方法 | 说明 |
|---|---|
Add(T item) | 向集合添加元素(若已满则阻塞) |
TryAdd(T item, TimeSpan timeout) | 尝试在指定时间内添加,超时返回 false |
Take() | 取出并移除一个元素(若为空则阻塞) |
TryTake(out T item, TimeSpan timeout) | 尝试在指定时间内取出,超时返回 false |
GetConsumingEnumerable() | 返回一个可枚举对象,自动阻塞并消费元素,直到调用 CompleteAdding() |
CompleteAdding() | 标记集合不再接受新元素,通知消费者即将结束 |
BlockingCollection 非常适合以下场景:
通过本文,你应该已经掌握了 C# BlockingCollection 的基本用法。它不仅简化了多线程编程中的数据传递逻辑,还通过阻塞机制天然实现了线程间的协调。无论是构建高性能服务器、后台任务处理系统,还是简单的并发应用,阻塞集合使用教程 中介绍的技术都能为你提供强大支持。
记住关键点:使用 GetConsumingEnumerable() + CompleteAdding() 是最推荐的消费方式;合理设置容量上限可以防止资源耗尽;所有操作都是线程安全的,无需额外加锁。
现在,你已经准备好在自己的项目中使用 多线程安全集合 来构建高效、稳定的并发程序了!
本文由主机测评网于2025-12-23发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251211961.html