编辑
2025-09-18
C#
00

目录

ConcurrentQueue简介
ConcurrentQueue的特点
ConcurrentQueue的基本用法
创建ConcurrentQueue
入队(Enqueue)
出队(TryDequeue)
查看队列首元素(TryPeek)
实例:使用ConcurrentQueue实现简单的任务队列
Winform例子
总结

在多线程环境下,数据结构的线程安全性至关重要。C#为了满足并发编程的需求,提供了一系列线程安全的集合,其中ConcurrentQueue<T>是一个非常实用的类。本文将深入探讨ConcurrentQueue<T>的特点,并通过实例来展示其用法。

ConcurrentQueue简介

ConcurrentQueue<T>是.NET Framework中System.Collections.Concurrent命名空间下的一个类,它表示一个线程安全的先进先出(FIFO)的队列。与普通的队列相比,ConcurrentQueue<T>在多线程环境下进行入队(Enqueue)和出队(Dequeue)操作时无需额外的锁定或同步操作,因此,在高并发场景下性能表现优异。

ConcurrentQueue的特点

  • 线程安全ConcurrentQueue<T>内部采用了高效的锁策略,确保了在多线程环境下的线程安全。
  • 无锁设计:尽管是线程安全的,但ConcurrentQueue<T>大多数操作实际上是通过无锁设计实现的,这意味着它能够在高并发场景下保持高性能。
  • 支持并发操作:支持多个线程同时执行入队和出队操作,而不会导致数据损坏。

ConcurrentQueue的基本用法

创建ConcurrentQueue

创建ConcurrentQueue<T>的实例非常简单,如下所示:

C#
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();

入队(Enqueue)

ConcurrentQueue<T>中添加元素使用Enqueue方法:

C#
queue.Enqueue(1); queue.Enqueue(2);

出队(TryDequeue)

ConcurrentQueue<T>中移除并返回元素使用TryDequeue方法。此方法在成功移除元素时返回true,否则返回false

C#
int result; if (queue.TryDequeue(out result)) { Console.WriteLine($"Dequeued: {result}"); }

查看队列首元素(TryPeek)

不移除元素的情况下返回队列首元素使用TryPeek方法:

C#
int result; if (queue.TryPeek(out result)) { Console.WriteLine($"Front item: {result}"); }

实例:使用ConcurrentQueue实现简单的任务队列

以下示例展示了如何使用ConcurrentQueue<T>实现一个简单的任务队列,多个线程可以同时向队列中添加任务和从队列中取出任务执行。

C#
using System; using System.Collections.Concurrent; using System.Threading; using System.Threading.Tasks; class Program { static void Main(string[] args) { ConcurrentQueue<Action> taskQueue = new ConcurrentQueue<Action>(); int numberOfTasks = 10; // 生产者:添加任务到队列 for (int i = 0; i < numberOfTasks; i++) { int taskId = i; taskQueue.Enqueue(() => { Console.WriteLine($"Task {taskId} is running on thread {Thread.CurrentThread.ManagedThreadId}."); }); } // 消费者:执行队列中的任务 Task[] workers = new Task[3]; for (int i = 0; i < workers.Length; i++) { workers[i] = Task.Run(() => { while (taskQueue.TryDequeue(out Action task)) { task(); } }); } Task.WaitAll(workers); Console.WriteLine("All tasks have been executed."); } }

image.png

在这个示例中,我们创建了一个ConcurrentQueue<Action>来存储任务。然后,我们添加了10个简单的任务到队列中。最后,我们启动了3个工作线程(通过Task)来并发地执行队列中的任务。

Winform例子

C#
private ConcurrentQueue<string> messageQueue = new ConcurrentQueue<string>(); private System.Timers.Timer uiUpdateTimer; public Form1() { InitializeComponent(); InitializeUiUpdateTimer(); } private void InitializeUiUpdateTimer() { uiUpdateTimer = new System.Timers.Timer(); uiUpdateTimer.Interval = 100; // 更新UI的频率,这里设置为每100毫秒检查一次 uiUpdateTimer.Elapsed += UiUpdateTimer_Elapsed; uiUpdateTimer.Start(); } private void UiUpdateTimer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e) { while (messageQueue.TryDequeue(out string message)) { this.Invoke(() => { lstMessages.Items.Add(message); // 更新UI }); } } private void btnStart_Click(object sender, EventArgs e) { Task.Run(() => { // 模拟后台任务 for (int i = 0; i < 10; i++) { string message = $"Message {i + 1} from background thread."; messageQueue.Enqueue(message); // 将消息入队 Task.Delay(500).Wait(); // 模拟一些工作 } }); }

image.png

总结

ConcurrentQueue<T>是C#中一个非常有用的线程安全集合类,它通过高效的并发算法确保了在多线程环境下的高性能和线程安全。通过上述示例,我们可以看到ConcurrentQueue<T>在实现任务队列、消息队列等场景中的应用。掌握ConcurrentQueue<T>的使用,对于开发高效、可靠的多线程应用程序至关重要。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!