Background task

De Banane Atomic
Aller à la navigationAller à la recherche

Links

Description

In ASP.NET Core, background tasks can be implemented as hosted services.

Consuming a scoped service in a background task

MyBackgroundService.cs
public class MyBackgroundService(IServiceProvider services) : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using (var scope = Services.CreateScope())
        {
            var scopedService = scope.ServiceProvider.GetRequiredService<IMyScopedService>();
            await scopedService.DoWork(stoppingToken);
        }
    }

    public override async Task StopAsync(CancellationToken stoppingToken)
    {
        await base.StopAsync(stoppingToken);
    }
}
Program.cs
services.AddHostedService<MyBackgroundService>();
services.AddScoped<IMyScopedService, MyScopedService>();

Queued background tasks

BackgroundTaskQueue
public class BackgroundTaskQueue<T> : IBackgroundTaskQueue
{
    private readonly ConcurrentQueue<T> items = new();

    public void Enqueue(T item) => items.Enqueue(item);

    public T? Dequeue()
    {
        var success = items.TryDequeue(out var workItem);
        return success ? workItem : default;
    }
}

public interface IBackgroundTaskQueue<T>
{
    void Enqueue(T item);
    T? Dequeue();
}
QueuedHostedService.cs
public class QueuedHostedService(IBackgroundTaskQueue taskQueue) : BackgroundService
{
    public IBackgroundTaskQueue TaskQueue { get; } = taskQueue ;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var queuedTask = await TaskQueue.DequeueAsync(stoppingToken);

            try
            {
                await queuedTask(stoppingToken);
            }
            catch (Exception ex)
            { }
        }
    }
}
Program.cs
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue>(ctx =>
{
    if (!int.TryParse(hostContext.Configuration["QueueCapacity"], out var queueCapacity))
        queueCapacity = 100;
    return new BackgroundTaskQueue(queueCapacity);
});

Timed background tasks