Queue<T>(队列)
在 C# 中,Queue 是一个先进先出(FIFO, First In First Out)数据结构,属于集合的一个类。
Queue 属于 System.Collections 或 System.Collections.Generic 命名空间,分别提供非泛型和泛型版本的实现。Queue 适用于需要按照入队顺序处理数据的场景。
队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。
- 适用于单线程环境。
- 当确定不会有多个线程同时访问队列时。
- 当需要高性能且不需要处理线程安全问题时。
ConcurrentQueue<T>
ConcurrentQueue<T>作为.NET Framework 4.0 引入的线程安全集合,采用无锁算法(Lock-Free),能显著提升高并发场景下的性能。它特别适合在多线程环境中使用,无需额外的锁机制即可安全地进行并发操作。
- 适用于多线程环境。
- 当需要多个线程同时安全地访问和操作队列时。
- 当需要避免复杂的锁管理和潜在的死锁问题时。
基本概念
- ConcurrentQueue<T> 是一个线程安全的先进先出(FIFO)队列,属于 System.Collections.Concurrent 命名空间。它遵循先进先出(FIFO)的原则,允许多个线程同时对队列进行操作,而无需额外的锁机制。
- 用于在生产者和消费者场景中高效地处理数据。但需要注意的是,它并不保证元素在同一个线程内入队顺序和出队顺序完全一致。
基本用法
- 创建 ConcurrentQueue
using System.Collections.Concurrent;
// 创建空的 ConcurrentQueue
ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
// 使用集合初始化器创建并初始化
ConcurrentQueue<string> namedQueue = new ConcurrentQueue<string>(new[] { "A", "B", "C" });
- 入队操作 (Enqueue)
queue.Enqueue(1); // 将元素添加到队列末尾
queue.Enqueue(2);
queue.Enqueue(3);
- 出队操作 (TryDequeue)
if (queue.TryDequeue(out int result))
{
Console.WriteLine($"Dequeued: {result}");
}
else
{
Console.WriteLine("Queue is empty");
}
- 查看队首元素 (TryPeek)
if (queue.TryPeek(out int peekResult))
{
Console.WriteLine($"Peeked: {peekResult}");
}
- 检查队列是否为空
bool isEmpty = queue.IsEmpty;
示例
public partial class MainWindow : Window
{
private ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
public MainWindow()
{
InitializeComponent();
queue.Enqueue("1");
queue.Enqueue("2");
queue.Enqueue("3");
var str = queue.First();
Debug.Write($"======={str}");//1
string? result;
bool br = queue.TryDequeue(out result); // 尝试移除并返回队列开头的项目
Debug.Write($"++++++++{result}");//1
var str2 = queue.First();
Debug.Write($"======={str2}");//2
}
}