user12816917
user12816917

Reputation: 115

C# ASP.NET Core - run code periodically/automatically in a deployed web app/API

I'm sure there's a proper term for what I'm trying to do but I don't know it. I would like to "run" a program or a method in an API controller periodically. For example, in a database connected to my app, I have table A that gets populated from a client request, and table B that uses table A to populate itself. Table B shouldn't be populated during a client request because it would take too long, instead it would be convenient for a program to exist that refers to table A and populates table B periodically.

What is this practice called? How is it done in C#/ASP.NET Core and what are some best practices? FYI my ASP.NET Core REST API is deployed in Azure.

Thank you and stay safe out there!

Upvotes: 5

Views: 4230

Answers (2)

Andy Vaal
Andy Vaal

Reputation: 493

In ASP.NET Core you can run background tasks by creating a hosted service. You can read the full documentation here.

If you want to run the task periodically then a timed background task may be appropriate. An example taken straight from the documentation is:

public class TimedHostedService : IHostedService, IDisposable
{
    private int executionCount = 0;
    private readonly ILogger<TimedHostedService> _logger;
    private Timer _timer;

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

    public Task StartAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service running.");

        _timer = new Timer(DoWork, null, TimeSpan.Zero, 
            TimeSpan.FromSeconds(5));

        return Task.CompletedTask;
    }

    private void DoWork(object state)
    {
        var count = Interlocked.Increment(ref executionCount);

        _logger.LogInformation(
            "Timed Hosted Service is working. Count: {Count}", count);
    }

    public Task StopAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Timed Hosted Service is stopping.");

        _timer?.Change(Timeout.Infinite, 0);

        return Task.CompletedTask;
    }

    public void Dispose()
    {
        _timer?.Dispose();
    }
}

Perform your long running task in the DoWork method. Also note that it says Timer won't wait for your long running task to finish so it may be best to stop the timer first and resume it afterwards.

Don't forget to register your background task in the ConfigureServices method of your Startup class:

services.AddHostedService<TimedHostedService>();

Upvotes: 8

sidecus
sidecus

Reputation: 752

Architecturally I would suggest you separate those kind of heavy computation into other micro services, or leveraging current serverless capabilities in most cloud offerings.

If that's not feasible, asp.net core has something called "background services" which you can leverage to trigger certain tasks. Here is the document: Background tasks with hosted services in ASP.NET Core. It's available in 2.1 also.

Upvotes: 0

Related Questions