C#队列Queue多线程安全用法解析与修正

林见深
林见深
发布时间:2026-10-13| 2人浏览过
原创

在C#开发中,经常需要利用队列(Queue)在多线程之间传递数据。然而,基础的Queue类并非线程安全,且简单的轮询方式会导致CPU空转。本文将通过实例分析其用法,并指出潜在问题及更优的替代方案。

基础场景:多线程消费队列

在许多简单场景下,开发者会使用一个后台线程从主线程填充的 Queue<T> 中取出数据进行处理。以下是一个典型的代码结构演示:

private Queue<string> queue = new Queue<string>();

private void button_测试Queue结合多线程_Click(object sender, EventArgs e)
{
    Console.WriteLine("初始化队列");
    string[] cars = new string[]{"宝马","奔驰",
      "奥迪","东风","劳斯莱斯"};
    foreach (string str in cars)
    {
        queue.Enqueue(str);
        Console.WriteLine("入队列-{0}", str);
    }
    Console.WriteLine();
    Console.ForegroundColor = ConsoleColor.Red;
    
    // 创建后台线程进行打印
    Thread th = new Thread(new ThreadStart(printQueue));
    th.IsBackground = true; // 设置为后台线程,随主程序退出而结束
    th.Start();
}

private void printQueue()
{
    while (true)
    {
        if (queue.Count > 0)
        {
            Console.WriteLine("出队列-{0}", queue.Dequeue());
        }
    }
}

该段代码执行后,控制台将依次输出车辆的出队信息。运行结果如下:

代码缺陷与风险分析

尽管上述代码可以完成基本的数据传输任务,但在实际生产环境中,它存在两个严重问题:

  1. CPU 空转(Busy Waiting): printQueue 方法中的 while(true) 循环会在队列为空时持续执行判断逻辑,导致CPU占用率飙升。正确的做法是使用阻塞机制或事件通知。
  2. 线程不安全: System.Collections.Queue 和 Queue<T> 都不是线程安全的。如果主线程在子线程读取的同时进行写入(Enqueue/Dequeue),可能会引发异常或数据竞争。

优化方案:使用 ConcurrentQueue 或 Lock

为了构建健壮的多线程队列系统,建议采用以下两种方式之一:

第1步:使用 System.Threading.Channels 或 BlockingCollection

这是 .NET Core / .NET 5+ 推荐的方式,天然支持生产者-消费者模式,具备阻塞能力:

using System.Threading.Tasks.Dataflow;

// 使用 BufferBlock 实现背压和阻塞
var block = new ActionBlock<string>(async item =>
{
    Console.WriteLine($"消费: {item}");
});

foreach (var car in cars)
{
    await block.SendAsync(car);
}
block.Complete();
await block.Completion;

第2步:使用 lock 关键字保护传统 Queue

如果必须使用旧版框架或简单场景,务必在访问 Queue 时加锁:

private readonly object _lock = new object();
private Queue<string> _queue = new Queue<string>;

public void SafeDequeue(out string item)
{
    lock (_lock)
    {
        if (_queue.Count > 0)
        {
            item = _queue.Dequeue();
        }
        else
        {
            item = null;
        }
    }
}

以上就是C#队列Queue多线程用法的详细内容,更多关于C#并发编程与线程安全的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。