Reputation: 310
I have an class which derives from IHostedService
. In here I have the override method StartAsync
as shown below:
public Task StartAsync(CancellationToken cancellationToken)
{
_timer = new Timer(DoSomething, null, offset, TimeSpan.FromHours(1));
return Task.CompletedTask;
}
In here I have the variable offset which is of the TimeSpan class.
What I need:
I need to calculate the offset in such way that the task "DoSomething" will be executed every start of an hour, like: 10:00, 13:00, 21:00 or 00:00. So this offset needs to be in minutes.
Example :
Let's say the application starts running at 13:48PM
, the correct offset would be 12 minutes and the next hour would be 14
.
My question: How would I calculate the offset which is in minutes until next hour ?
Upvotes: 1
Views: 2868
Reputation: 50712
In the Microsoft Documentation, there is official version of TimedHostedService
class
You can use cron parsing nuget pacakge (NCronTab.signed) to calculate the time based on configuration, and it will become a nice looking solution
public class TimedHostedService : IHostedService, IDisposable
{
private readonly ILogger<TimedHostedService> _logger;
private Timer _timer;
private readonly CrontabSchedule _cronSchedule;
public TimedHostedService(ILogger<TimedHostedService> logger)
{
_logger = logger;
_cronSchedule = CrontabSchedule.Parse("0 * * * *");
}
public Task StartAsync(CancellationToken stoppingToken)
{
var now = DateTime.Now;
var nextOccurance = _cronSchedule.GetNextOccurrence(now);
_logger.LogInformation("Configuring next run at: {time}", nextOccurance);
await Task.Delay(nextOccurance - now, stoppingToken);
DoWork()
return Task.CompletedTask;
}
private void DoWork()
{
_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();
}
}
Upvotes: 1
Reputation: 310
My answer would be:
TimeSpan offset = TimeSpan.FromMinutes(60 - DateTimeOffset.UtcNow.Minute);
But is there any other (better)way to implement this ?
Upvotes: 0
Reputation: 836
something like
var minutes = (DateTime.Today.AddHours(DateTime.Now.Hour+1)-DateTime.Now).TotalMinutes
should do the trick
Upvotes: 2