← Назад к вопросам

Как реализовать background tasks (фоновые задачи) в ASP.NET Core? Что такое IHostedService?

2.3 Middle🔥 132 комментариев
#Базы данных и SQL

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Реализация фоновых задач в ASP.NET Core

В ASP.NET Core существует несколько подходов для реализации фоновых задач, которые выполняются независимо от HTTP-запросов.

Основные подходы

1. IHostedService и BackgroundService Наиболее рекомендуемый способ для долгосрочных фоновых задач. IHostedService - это базовый интерфейс, который позволяет запускать фоновые задачи вместе с хостом приложения.

public interface IHostedService
{
    Task StartAsync(CancellationToken cancellationToken);
    Task StopAsync(CancellationToken cancellationToken);
}

Для упрощения реализации используется абстрактный класс BackgroundService:

public abstract class BackgroundService : IHostedService, IDisposable
{
    private Task _executingTask;
    private readonly CancellationTokenSource _stoppingCts = new();

    protected abstract Task ExecuteAsync(CancellationToken stoppingToken);

    public virtual Task StartAsync(CancellationToken cancellationToken)
    {
        _executingTask = ExecuteAsync(_stoppingCts.Token);
        return _executingTask.IsCompleted ? _executingTask : Task.CompletedTask;
    }

    public virtual async Task StopAsync(CancellationToken cancellationToken)
    {
        if (_executingTask == null) return;
        
        try
        {
            _stoppingCts.Cancel();
        }
        finally
        {
            await Task.WhenAny(_executingTask, 
                Task.Delay(Timeout.Infinite, cancellationToken));
        }
    }
}

Пример реализации фоновой задачи:

public class TimedBackgroundService : BackgroundService
{
    private readonly ILogger<TimedBackgroundService> _logger;
    private readonly PeriodicTimer _timer = new(TimeSpan.FromMinutes(5));

    public TimedBackgroundService(ILogger<TimedBackgroundService> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (await _timer.WaitForNextTickAsync(stoppingToken) 
               && !stoppingToken.IsCancellationRequested)
        {
            try
            {
                _logger.LogInformation("Выполнение фоновой задачи в: {time}", 
                    DateTimeOffset.Now);
                
                // Ваша бизнес-логика
                await ProcessDataAsync(stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Ошибка в фоновой задаче");
            }
        }
    }

    private async Task ProcessDataAsync(CancellationToken cancellationToken)
    {
        // Реализация обработки данных
        await Task.Delay(1000, cancellationToken);
    }
}

Регистрация в Program.cs:

builder.Services.AddHostedService<TimedBackgroundService>();

2. Worker Services Отдельный тип проекта для создания длительно работающих служб:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

3. Hangfire и Quartz.NET Библиотеки для продвинутого планирования задач:

// Пример Hangfire
services.AddHangfire(config => 
    config.UseSqlServerStorage(connectionString));
services.AddHangfireServer();

// Регистрация рекуррентной задачи
RecurringJob.AddOrUpdate<IMyService>(
    "my-recurring-job",
    service => service.ProcessData(),
    Cron.Daily);

Ключевые аспекты реализации

Обработка ошибок:

protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
    while (!stoppingToken.IsCancellationRequested)
    {
        try
        {
            await DoWorkAsync(stoppingToken);
        }
        catch (Exception ex) when (ex is not OperationCanceledException)
        {
            _logger.LogError(ex, "Ошибка выполнения задачи");
            await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
        }
    }
}

Инъекция зависимостей:

public class DataProcessingService : BackgroundService
{
    private readonly IServiceScopeFactory _scopeFactory;
    
    public DataProcessingService(IServiceScopeFactory scopeFactory)
    {
        _scopeFactory = scopeFactory;
    }
    
    protected override async Task ExecuteAsync(CancellationToken token)
    {
        using var scope = _scopeFactory.CreateScope();
        var repository = scope.ServiceProvider
            .GetRequiredService<IDataRepository>();
        // Использование скоупированных зависимостей
    }
}

Рекомендации по использованию

  • Для простых периодических задач используйте BackgroundService
  • Для сложного планирования рассмотрите Hangfire или Quartz.NET
  • Всегда реализуйте корректную остановку через CancellationToken
  • Используйте скоупы для работы с зависимостями с временем жизни Scoped
  • Добавляйте логирование для отслеживания выполнения задач
  • Конфигурируйте интервалы через appsettings.json
  • Тестируйте остановку приложения для избежания утечек ресурсов

Конфигурация через appsettings.json

{
  "BackgroundTasks": {
    "DataProcessing": {
      "IntervalInMinutes": 5,
      "Enabled": true,
      "BatchSize": 100
    }
  }
}

IHostedService является фундаментальным строительным блоком для фоновых задач в ASP.NET Core, обеспечивая стандартизированный способ интеграции длительных операций в жизненный цикл приложения с поддержкой dependency injection, конфигурации и корректного завершения работы.