Skip to content

Instantly share code, notes, and snippets.

@dusan-tkac
Forked from changhuixu/CronJobService.cs
Last active February 2, 2021 04:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dusan-tkac/2233fddc136b13ea656fe3d5bd9f1061 to your computer and use it in GitHub Desktop.
Save dusan-tkac/2233fddc136b13ea656fe3d5bd9f1061 to your computer and use it in GitHub Desktop.
schedule cron job. IHostedService, asp.net core
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