The answer from FlashOver is correct -- ExecuteAsync
is called once. Not repeatedly.
If you want to have something happen at a specific time in a IHostedService
, read this article from Microsoft.
I will paste the code here in case the link rots away:
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();
}
}
Inject it as so:
services.AddHostedService<TimedHostedService>();
Now, keep in mind that if your application scales horizontally where you have more than one instance then you will have more than one timer running. This generally is not a good thing.
In cases where I need a task to run at a specific time of day I use an Azure Function set up as a CRON job.