C# (.NET) 中的任务队列:System.Threading.Channels、Hangfire 和 RabbitMQ

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# (.NET) 任务队列:从简单到复杂



现代 C# (.NET) 开发很少能离开后台任务、延迟处理和异步操作。任务队列(Job Queues / Message Queues)是一种关键模式,可以减轻应用程序主线程的负担,保证消息传递并实现处理能力的扩展。在本文中,我们将探讨在 .NET 中实现队列的三种流行方法:内置的 System.Threading.Channels、强大的调度器 Hangfire 以及工业级消息代理 RabbitMQ(搭配 .NET 客户端)。



1. System.Threading.Channels — .NET 内置队列



System.Threading.Channels 是一个轻量级、线程安全的队列,可直接在 .NET 中使用(自 .NET Core 2.1 起)。它非常适合单进程内的“生产者-消费者”场景。



主要功能:

  • 异步读写(await writer.WriteAsync()、await reader.ReadAsync())。
  • 有界和无界通道(Bounded / Unbounded)。
  • 通过 CancellationToken 支持取消操作。
  • 批量读取(ReadAllAsync)。


示例:简单的任务队列

using System.Threading.Channels;

// 创建一个容量为 100 的通道var channel = Channel.CreateBounded<string>(100);

// 生产者:添加任务var producer = Task.Run(async () =>{ for (int i = 0; i < 10; i++) { await channel.Writer.WriteAsync($"任务 {i}"); await Task.Delay(100); } channel.Writer.Complete(); // 发送完成信号});

// 消费者:处理任务var consumer = Task.Run(async () =>{ await foreach (var item in channel.Reader.ReadAllAsync()) { Console.WriteLine($"已处理: {item}"); }});

await Task.WhenAll(producer, consumer);


优点:零依赖、高性能,非常适合单应用内的内存队列。
缺点:不适用于分布式系统——重启时数据会丢失。



2. Hangfire — 高级后台任务调度器



Hangfire 是一个流行的 .NET 库,它不仅实现队列功能,还提供 Web 仪表盘、持久化(SQL Server、Redis、PostgreSQL)、重试机制和 CRON 调度。



关键功能:

  • 即发即忘(Fire-and-forget,一次性执行)。
  • 延迟任务(Delayed)。
  • 重复任务(Recurring)——替代 Windows 任务计划程序。
  • 自动重试,支持可配置策略。
  • 内置监控(仪表盘)。


示例:Hangfire 基本配置

// 安装:Install-Package Hangfireusing Hangfire;using Hangfire.SqlServer;

// 在 Program.cs 中配置 (.NET 6+)var builder = WebApplication.CreateBuilder(args);builder.Services.AddHangfire(config => config.UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireDb")));builder.Services.AddHangfireServer();

var app = builder.Build();app.UseHangfireDashboard(); // /hangfire

// 添加任务BackgroundJob.Enqueue(() => Console.WriteLine("即发即忘!"));BackgroundJob.Schedule(() => Console.WriteLine("5 分钟后执行"), TimeSpan.FromMinutes(5));RecurringJob.AddOrUpdate("my-job", () => Console.WriteLine("每分钟执行"), Cron.Minutely);

app.Run();


优点:功能丰富、重启后状态保留、自带 UI。
缺点:需要数据库,不适用于高负载分布式系统(针对单体应用设计)。



3. RabbitMQ + .NET — 分布式消息队列



RabbitMQ

推荐