I am working on a project based on ASP.NET Core 3.1 and I want to add a specific functionality to it to schedule publishing a post in the future in a date and time specified by post author (something like what Wordpress does for scheduled posts through its cron jobs). For example, if we receive this date and time from user :
2020-09-07 14:08:07
Then, how can I schedule a background task for it by using hosted services to run only for one time and to change a flag in database and save changes after that?
I've read some articles about it but they didn't specify date and time and just mentioned repeated tasks for every 5 second and stuff like that with cron expressions, but, the thing I need to know is how can I schedule a background task for a specific date and time?
Thank you in advance.
I combined CrontabSchedule with IHostedService. The implementation below is lightweight (no architecture imposing libs) and no polling.
public class SomeScheduledService: IHostedService
{
private readonly CrontabSchedule _crontabSchedule;
private DateTime _nextRun;
private const string Schedule = "0 0 1 * * *"; // run day at 1 am
private readonly SomeTask _task;
public SomeScheduledService(SomeTask task)
{
_task = Task;
_crontabSchedule = CrontabSchedule.Parse(Schedule, new CrontabSchedule.ParseOptions{IncludingSeconds = true});
_nextRun = _crontabSchedule.GetNextOccurrence(DateTime.Now);
}
public Task StartAsync(CancellationToken cancellationToken)
{
Task.Run(async () =>
{
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(UntilNextExecution(), cancellationToken); // wait until next time
await _task.Execute(); //execute some task
_nextRun = _crontabSchedule.GetNextOccurrence(DateTime.Now);
}
}, cancellationToken);
return Task.CompletedTask;
}
private int UntilNextExecution() => Math.Max(0, (int)_nextRun.Subtract(DateTime.Now).TotalMilliseconds);
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}