C# 队列的各种使用方法 private static ConcurrentQueue
在C#中,ConcurrentQueue<T> 是一个线程安全的先进先出(FIFO)集合,它位于 System.Collections.Concurrent 命名空间中。它非常适合在多线程环境中使用,因为它提供了一些原子操作来确保线程安全。
以下是一些常见的 ConcurrentQueue<T> 使用方法,以 ConcurrentQueue<string> 为例:
1. 初始化队列
using System;
using System.Collections.Concurrent;
class Program
{
private static ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
static void Main(string[] args)
{
// 其他代码
}
}
2. 入队(Enqueue)
使用 Enqueue
方法将元素添加到队列的末尾。
queue.Enqueue("First item");
queue.Enqueue("Second item");
3. 出队(Dequeue)
使用 TryDequeue
方法从队列的开头移除并返回元素。这是一个返回布尔值的操作,因为队列可能为空。
if (queue.TryDequeue(out string result))
{
Console.WriteLine($"Dequeued: {result}");
}
else
{
Console.WriteLine("Queue is empty.");
}
4. 查看队首元素(Peek)
使用 TryPeek
方法查看队列的开头元素但不移除它。
if (queue.TryPeek(out string peekResult))
{
Console.WriteLine($"Peek: {peekResult}");
}
else
{
Console.WriteLine("Queue is empty.");
}
5. 检查队列是否为空
虽然 TryDequeue
和 TryPeek
可以通过返回值检查队列是否为空,但你也可以直接检查 IsEmpty
属性。
if (queue.IsEmpty)
{
Console.WriteLine("Queue is empty.");
}
else
{
Console.WriteLine("Queue is not empty.");
}
6. 遍历队列
虽然 ConcurrentQueue<T>
不支持直接遍历(因为遍历期间可能会有其他线程修改队列),但你可以通过循环和 TryDequeue
方法安全地遍历所有元素,同时清空队列。
while (!queue.IsEmpty)
{
if (queue.TryDequeue(out string item))
{
Console.WriteLine(item);
}
}
或者,如果你不想清空队列,可以使用一个临时队列来复制元素,然后遍历临时队列:
ConcurrentQueue<string> tempQueue = new ConcurrentQueue<string>(queue);
foreach (var item in tempQueue)
{
Console.WriteLine(item);
}
7. 线程安全操作
ConcurrentQueue<T>
的所有公共和受保护成员都是线程安全的,并且可以在多个线程上并发使用,而无需额外的锁定。
示例代码
以下是一个完整的示例,展示了上述方法的使用:
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
class Program
{
private static ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
static void Main(string[] args)
{
// 入队
queue.Enqueue("Item 1");
queue.Enqueue("Item 2");
queue.Enqueue("Item 3");
// 查看队首元素
if (queue.TryPeek(out string peekResult))
{
Console.WriteLine($"Peek: {peekResult}");
}
// 并发处理
Parallel.For(0, 5, i =>
{
ProcessQueue();
});
// 清空并遍历队列
while (!queue.IsEmpty)
{
if (queue.TryDequeue(out string item))
{
Console.WriteLine($"Dequeued: {item}");
}
}
}
static void ProcessQueue()
{
while (!queue.IsEmpty)
{
if (queue.TryDequeue(out string item))
{
Console.WriteLine($"Thread {Task.CurrentId} processed: {item}");
}
}
}
}
请注意,由于多个线程同时尝试处理队列,因此某些元素可能会被多个线程检查到但只有一个线程能成功出队。这就是 ConcurrentQueue<T>
线程安全性的体现。