Carrie Kaski
Carrie Kaski

Reputation: 197

Periodic Timer force to run every second

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

Upvotes: 0

Views: 878

Answers (1)

Ceemah Four
Ceemah Four

Reputation: 518

you can chose not to await the job.ProcessAsync() which would allow your code to continue waiting for the next tick.

_ = job.ProcessAsync();

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.

Upvotes: 1

Related Questions