Hangfire для C# (.NET): полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Что такое Hangfire и зачем она нужна?

Hangfire — это мощная и популярная библиотека для C# (.NET), предназначенная для выполнения фоновых задач (background jobs). В современной веб-разработке часто возникает необходимость выполнять операции, которые не должны блокировать основной поток выполнения приложения. Например: отправка email-уведомлений, генерация отчетов, обработка загруженных файлов, синхронизация данных с внешними API, очистка устаревших записей в базе данных и многое другое.

Hangfire предоставляет простой, но гибкий способ запускать такие задачи. Ключевые возможности библиотеки:

  • Выполнение задач в фоне: Задачи выполняются асинхронно, не блокируя ответ пользователю.
  • Планирование: Можно запускать задачи по расписанию (cron-выражения) или с задержкой.
  • Надежность: Hangfire сохраняет информацию о задачах в постоянном хранилище (база данных). Даже если приложение перезапустится, незавершенные задачи будут выполнены.
  • Мониторинг: Встроенный веб-интерфейс (Dashboard) позволяет отслеживать статус задач, просматривать логи, повторно запускать упавшие задачи.
  • Повторные попытки: Если задача завершилась ошибкой, Hangfire автоматически попытается выполнить ее снова (с настраиваемой политикой повторных попыток).
  • Интеграция с DI: Легко интегрируется с контейнерами внедрения зависимостей (Dependency Injection) в ASP.NET Core.

Hangfire поддерживает различные хранилища: SQL Server, PostgreSQL, Redis, MongoDB и другие. Это делает ее подходящей для проектов любого масштаба — от небольших сайтов до высоконагруженных корпоративных систем.

Установка

Hangfire устанавливается через NuGet Package Manager. В отличие от Python, где используется pip install, в .NET экосистеме используется dotnet add package или менеджер пакетов Visual Studio.

Для установки базового пакета Hangfire выполните команду в терминале (в корневой папке вашего проекта):

dotnet add package Hangfire

Эта команда установит ядро Hangfire и зависимости для хранения задач в памяти (InMemory). Для продакшн-среды вам понадобится установить пакет для конкретной базы данных, например:

  • SQL Server: dotnet add package Hangfire.SqlServer
  • PostgreSQL: dotnet add package Hangfire.PostgreSql
  • Redis: dotnet add package Hangfire.Redis

После установки пакетов, необходимо настроить Hangfire в файле Program.cs (для ASP.NET Core) или Startup.cs.

Быстрый старт

Рассмотрим минимальный пример настройки и использования Hangfire в ASP.NET Core приложении.

Шаг 1: Настройка в Program.cs

using Hangfire;
using Hangfire.SqlServer;

var builder = WebApplication.CreateBuilder(args);

// Добавление Hangfire с хранилищем SQL Server
builder.Services.AddHangfire(configuration => configuration
    .SetDataCompatibilityLevel(CompatibilityLevel.Version_180)
    .UseSimpleAssemblyNameTypeSerializer()
    .UseRecommendedSerializerSettings()
    .UseSqlServerStorage(builder.Configuration.GetConnectionString("HangfireConnection")));

// Добавление сервера Hangfire
builder.Services.AddHangfireServer();

var app = builder.Build();

// Включение Dashboard (панели мониторинга)
app.UseHangfireDashboard();

// Пример простого фонового задания
app.MapGet("/fire-and-forget", () =>
{
    var jobId = BackgroundJob.Enqueue(() => Console.WriteLine("Hello from Hangfire!"));
    return $"Job {jobId} has been enqueued.";
});

app.Run();

Шаг 2: Создание задачи

В примере выше мы использовали метод BackgroundJob.Enqueue. Это создает задачу типа "Fire-and-Forget" (запустил и забыл). Она будет выполнена немедленно в фоновом потоке.

Шаг 3: Запуск приложения

Перейдите по адресу /hangfire в вашем браузере, чтобы увидеть панель мониторинга. Перейдите по адресу /fire-and-forget, чтобы создать новую задачу. Вы увидите, как она появится в Dashboard и будет выполнена.

Основные методы/функции

Hangfire предоставляет богатый API для работы с фоновыми задачами. Рассмотрим 10 ключевых методов.

1. BackgroundJob.Enqueue

Описание: Создает задачу типа "Fire-and-Forget". Задача помещается в очередь и выполняется немедленно (как только освободится рабочий процесс).

Параметры:

  • Expression<Action> или Expression<Func<Task>> — лямбда-выражение, описывающее выполняемый метод.
  • string queue (необязательный) — имя очереди (по умолчанию "default").

Пример:

// Простая задача
BackgroundJob.Enqueue(() => Console.WriteLine("Task executed"));

// Задача с параметром
int userId = 123;
BackgroundJob.Enqueue(() => SendEmail(userId));

// Асинхронная задача
BackgroundJob.Enqueue(() => ProcessFileAsync("path/to/file"));

// Задача в конкретной очереди
BackgroundJob.Enqueue(() => HeavyComputation(), "critical");

2. BackgroundJob.Schedule

Описание: Создает отложенную задачу. Задача будет выполнена через указанный промежуток времени.

Параметры:

  • Expression<Action> или Expression<Func<Task>> — лямбда-выражение.
  • TimeSpan delay — задержка перед выполнением.
  • string queue (необязательный) — имя очереди.

Пример:

// Задача через 1 час
BackgroundJob.Schedule(() => Console.WriteLine("Delayed task"), TimeSpan.FromHours(1));

// Задача через 10 минут
BackgroundJob.Schedule(() => SendReminderEmail("user@example.com"), TimeSpan.FromMinutes(10));

// Задача с использованием DateTimeOffset
BackgroundJob.Schedule(() => ProcessReport(), DateTimeOffset.Now.AddDays(1));

3. RecurringJob.AddOrUpdate

Описание: Создает или обновляет повторяющуюся задачу (cron job). Задача будет выполняться по заданному расписанию.

Параметры:

  • string recurringJobId — уникальный идентификатор задачи.
  • Expression<Action> или Expression<Func<Task>> — лямбда-выражение.
  • string cronExpression — cron-выражение, описывающее расписание.
  • string queue (необязательный) — имя очереди.

Пример:

// Каждую минуту
RecurringJob.AddOrUpdate("minute-job", () => Console.WriteLine("Every minute"), Cron.Minutely());

// Каждый день в полночь
RecurringJob.AddOrUpdate("daily-cleanup", () => CleanOldRecords(), Cron.Daily());

// Каждый час
RecurringJob.AddOrUpdate("hourly-report", () => GenerateHourlyReport(), "0 * * * *");

// Каждую пятницу в 18:00
RecurringJob.AddOrUpdate("weekly-backup", () => BackupDatabase(), "0 18 * * 5");

4. BackgroundJob.Delete

Описание: Удаляет задачу из очереди. Если задача уже выполняется, она не будет прервана, но повторные попытки (если они были запланированы) будут отменены.

Параметры:

  • string jobId — идентификатор задачи, полученный при создании.

Пример:

var jobId = BackgroundJob.Enqueue(() => SomeMethod());
// Позже, если нужно отменить
BackgroundJob.Delete(jobId);

5. BackgroundJob.Requeue

Описание: Перемещает задачу обратно в очередь для повторного выполнения. Полезно, если задача завершилась с ошибкой, и вы хотите попробовать снова вручную.

Параметры:

  • string jobId — идентификатор задачи.

Пример:

var jobId = BackgroundJob.Enqueue(() => UnstableMethod());
// Если задача упала, можно перезапустить
BackgroundJob.Requeue(jobId);

6. RecurringJob.RemoveIfExists

Описание: Удаляет повторяющуюся задачу по ее идентификатору.

Параметры:

  • string recurringJobId — идентификатор повторяющейся задачи.

Пример:

RecurringJob.RemoveIfExists("daily-cleanup");

7. RecurringJob.Trigger

Описание: Немедленно запускает повторяющуюся задачу вне зависимости от ее расписания.

Параметры:

  • string recurringJobId — идентификатор повторяющейся задачи.

Пример:

RecurringJob.Trigger("hourly-report"); // Запустить сейчас

8. IBackgroundJobClient.Create

Описание: Более продвинутый способ создания задачи. Позволяет задавать дополнительные параметры, такие как очередь, задержка, приоритет и т.д. Используется, когда нужно больше контроля.

Параметры:

  • Job job — объект, описывающий задачу.
  • EnqueuedState state — начальное состояние задачи.

Пример:

var client = new BackgroundJobClient();
var job = Job.FromExpression(() => SomeMethod());
var state = new EnqueuedState("critical");
var jobId = client.Create(job, state);

9. IMonitoringApi

Описание: Интерфейс для программного мониторинга состояния задач. Позволяет получать статистику, список задач, детали ошибок и т.д.

Пример:

var monitor = JobStorage.Current.GetMonitoringApi();
var statistics = monitor.GetStatistics();
Console.WriteLine($"Enqueued: {statistics.Enqueued}");
Console.WriteLine($"Failed: {statistics.Failed}");
Console.WriteLine($"Succeeded: {statistics.Succeeded}");

// Получить последние 10 упавших задач
var failedJobs = monitor.FailedJobs(0, 10);

10. IBackgroundJobClient.ChangeState

Описание: Позволяет изменить состояние задачи. Например, можно перевести задачу из состояния "Failed" в "Enqueued" для повторного выполнения.

Параметры:

  • string jobId — идентификатор задачи.
  • IState state — новое состояние.

Пример:

var client = new BackgroundJobClient();
client.ChangeState(jobId, new EnqueuedState());

Реальный практический пример использования

Рассмотрим сценарий: интернет-магазин. После оформления заказа необходимо выполнить несколько действий: отправить email покупателю, обновить складские остатки и создать задачу для службы доставки. Все эти операции должны выполняться асинхронно, чтобы не задерживать пользователя.

Создадим сервис для обработки заказа:

public class OrderProcessingService
{
    private readonly IBackgroundJobClient _backgroundJobs;

    public OrderProcessingService(                    

Рекомендаций