ASP.NET Core › Background Tasks & Hosted Services

How would you implement a cron-like scheduled background job (e.g., 'run daily at 2 AM') without a third-party scheduling library?

Advanced

Answer

Inside ExecuteAsync's loop, use a library like Cronos to parse a cron expression and compute the next occurrence time, then Task.Delay until that exact moment before running the job and recalculating the next occurrence -- for more complex or distributed scheduling needs (multiple instances, persistence, retries, UI for managing jobs), dedicated libraries like Hangfire or Quartz.NET are usually preferred over hand-rolled scheduling.
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {
    var schedule = CronExpression.Parse("0 2 * * *");  // 2 AM daily
    while (!stoppingToken.IsCancellationRequested) {
        var next = schedule.GetNextOccurrence(DateTimeOffset.UtcNow);
        var delay = next.Value - DateTimeOffset.UtcNow;
        await Task.Delay(delay, stoppingToken);
        await RunNightlyReportAsync();
    }
}
Real-world example A reporting service runs a nightly summary job at exactly 2 AM using a cron expression parsed with Cronos, rather than hardcoding a fixed Task.Delay that would drift relative to wall-clock time across daylight saving transitions.

Common follow-ups: When should you reach for Hangfire or Quartz.NET instead of hand-rolling scheduling?;How do you handle a missed scheduled run if the application was down at the scheduled time?