-
-
Save dusan-tkac/2233fddc136b13ea656fe3d5bd9f1061 to your computer and use it in GitHub Desktop.
schedule cron job. IHostedService, asp.net core
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public abstract class CronJobService : IHostedService, IDisposable | |
{ | |
private System.Timers.Timer _timer; | |
private readonly CronExpression _expression; | |
private readonly TimeZoneInfo _timeZoneInfo; | |
protected CronJobService(string cronExpression, TimeZoneInfo timeZoneInfo) | |
{ | |
_expression = CronExpression.Parse(cronExpression); | |
_timeZoneInfo = timeZoneInfo; | |
} | |
public virtual async Task StartAsync(CancellationToken cancellationToken) | |
{ | |
await ScheduleJob(cancellationToken); | |
} | |
protected virtual async Task ScheduleJob(CancellationToken cancellationToken) | |
{ | |
var next = _expression.GetNextOccurrence(DateTimeOffset.Now, _timeZoneInfo); | |
if (next.HasValue) | |
{ | |
var delay = next.Value - DateTimeOffset.Now; | |
// interval can be int.MaxValue at max | |
if (Math.Ceiling(delay.TotalMilliseconds) > int.MaxValue) | |
{ | |
// set timer to int.MaxValue | |
_timer = new System.Timers.Timer(int.MaxValue); | |
_timer.Elapsed += async (sender, args) => | |
{ | |
_timer.Dispose(); // reset and dispose timer | |
_timer = null; | |
// no work to be done here, this is in between desired executions | |
//if (!cancellationToken.IsCancellationRequested) | |
//{ | |
// await DoWork(cancellationToken); | |
//} | |
if (!cancellationToken.IsCancellationRequested) | |
{ | |
await ScheduleJob(cancellationToken); // reschedule next | |
} | |
}; | |
_timer.Start(); | |
} | |
else | |
{ | |
_timer = new System.Timers.Timer(delay.TotalMilliseconds); | |
_timer.Elapsed += async (sender, args) => | |
{ | |
_timer.Dispose(); // reset and dispose timer | |
_timer = null; | |
if (!cancellationToken.IsCancellationRequested) | |
{ | |
await DoWork(cancellationToken); | |
} | |
if (!cancellationToken.IsCancellationRequested) | |
{ | |
await ScheduleJob(cancellationToken); // reschedule next | |
} | |
}; | |
_timer.Start(); | |
} | |
} | |
await Task.CompletedTask; | |
} | |
public virtual async Task DoWork(CancellationToken cancellationToken) | |
{ | |
await Task.Delay(5000, cancellationToken); // do the work | |
} | |
public virtual async Task StopAsync(CancellationToken cancellationToken) | |
{ | |
_timer?.Stop(); | |
await Task.CompletedTask; | |
} | |
public virtual void Dispose() | |
{ | |
_timer?.Dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment