I create the periodic timer which run under background service
public class PeriodicHostedService : BackgroundService
{
private readonly TimeSpan period = TimeSpan.FromSeconds(1);
private readonly ILogger<PeriodicHostedService> logger;
private readonly IServiceScopeFactory factory;
private int executionCount = 0;
public PeriodicHostedService(ILogger<PeriodicHostedService> logger, IServiceScopeFactory factory)
{
this.logger=logger;
this.factory=factory;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using PeriodicTimer timer = new(period);
using var scope = factory.CreateScope();
ITimerJob job = scope.ServiceProvider.GetRequiredService<ITimerJob>();
while (
!stoppingToken.IsCancellationRequested &&
await timer.WaitForNextTickAsync(stoppingToken))
{
try
{
await job.ProcessAsync();
executionCount++;
logger.LogInformation($"Executed PeriodicHostedService - Count: {executionCount}");
}
catch (Exception ex)
{
logger.LogInformation($"Failed to execute PeriodicHostedService with exception message {ex.Message}. Good luck next round!");
}
}
}
}
I have set the timer run every second however, I have job in timer need to run over 1 second just an example
internal class TimerJob : ITimerJob
{
private int runningID;
public async Task ProcessAsync()
{
runningID++;
Console.WriteLine($"{DateTime.Now} > Current Running ID : {runningID}");
await LongTimeJob();
}
private async Task LongTimeJob ()
{
Console.WriteLine($"{DateTime.Now} > Step1 Async Job End ID : {runningID}");
await Task.Delay(3000).ConfigureAwait(false);
}
}
can I know how to write the timer which force to execute on every second (and let longtime job continue work) Thank you
you can chose not to await the job.ProcessAsync() which would allow your code to continue waiting for the next tick.
I must admit, running jobs every minute that are likely to run long might become a resource hog eventually. You should check your design for any unwanted side effects.