C# (.NET) 任务队列:从基础原语到工业级解决方案
组织异步任务处理是开发高负载 C# 应用程序的关键任务之一。在 .NET 生态系统中,有多种方法:从内置同步原语到强大的外部库。在本文中,我们将介绍处理任务队列的主要工具、它们的优势和使用示例。
1. System.Threading.Channels — .NET 内置工具
从 .NET Core 2.1 开始,标准库中引入了 System.Threading.Channels.Channel<T> 类。这是一个线程安全的队列,针对生产者-消费者场景进行了优化。
主要功能:
- 异步读写(
WriteAsync、ReadAsync) - 支持有界和无界队列
- 能够完成队列以向消费者发送信号
- 无锁的高性能
使用示例:
using System.Threading.Channels;
var channel = Channel.CreateBounded<string>(100);
// 生产者var producer = Task.Run(async () =>{ for (int i = 0; i < 10; i++) { await channel.Writer.WriteAsync($"Task {i}"); await Task.Delay(100); } channel.Writer.Complete();});
// 消费者var consumer = Task.Run(async () =>{ await foreach (var item in channel.Reader.ReadAllAsync()) { Console.WriteLine($"Processing: {item}"); await Task.Delay(200); }});
await Task.WhenAll(producer, consumer);何时使用:用于单个进程内的内部队列,当不需要持久化或分布式处理时。
2. Hangfire — 高级后台任务库
Hangfire 是 .NET 中最流行的管理后台任务的库之一。它支持队列、调度、重试和监控。
关键特性:
- 持久化(SQL Server、Redis、PostgreSQL 等)
- 用于监控的 Web 界面
- 支持延迟和重复任务
- 失败时自动重试
配置和使用示例:
// 安装:Install-Package Hangfire// 在 Startup.cs 中public void ConfigureServices(IServiceCollection services){ services.AddHangfire(config => config.UseSqlServerStorage(connectionString)); services.AddHangfireServer();}
// 使用public class EmailService{ public void SendWelcomeEmail(int userId) { // 发送电子邮件的逻辑 Console.WriteLine($"Sending email to user {userId}"); }}
// 将任务加入队列BackgroundJob.Enqueue<EmailService>(x => x.SendWelcomeEmail(42));
// 延迟任务BackgroundJob.Schedule<EmailService>( x => x.SendWelcomeEmail(43), TimeSpan.FromMinutes(5));何时使用:用于需要在重启之间保存任务、进行监控和灵活调度的 Web 应用程序。
3. RabbitMQ.Client — 分布式消息队列
对于多个服务需要交换任务的分布式系统,使用 RabbitMQ。RabbitMQ.Client 库提供对 AMQP 协议的完全访问。
生产者-消费者基本示例:
using RabbitMQ.Client;using System.Text;
// 生产者var factory = new ConnectionFactory() { HostName = "localhost" };using var connection = factory.CreateConnection();using var channel = connection.CreateModel();
channel.QueueDeclare(queue: "task_queue", durable: true, exclusive