Search code examples
c#.net-coretimerasp.net-core-hosted-services

How to run .net Core IHosted Service at specific time Of the day?


I am having the following Timer to run in .Net core Ihosted Service,

TimeSpan ScheduledTimespan;
string[] formats = { @"hh\:mm\:ss", "hh\\:mm" };
string strTime = Startup.Configuration["AppSettings:JobStartTime"].ToString();
var success = TimeSpan.TryParseExact(strTime, formats, CultureInfo.InvariantCulture, out ScheduledTimespan);
Timer _timer = new Timer(JobToRun, null, TimeSpan.Zero, ScheduledTimespan);

I'm using this specific overload,

public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period);

But JobToRun is executing as soon as the control reached to it. How do I make it run at a specific time of the day on an everyday basis? Thanks in advance.


Solution

  • Following function returns parsed job run time

    private static TimeSpan getScheduledParsedTime()
    {
         string[] formats = { @"hh\:mm\:ss", "hh\\:mm" };
         string jobStartTime = "07:10";
         TimeSpan.TryParseExact(jobStartTime, formats, CultureInfo.InvariantCulture, out TimeSpan ScheduledTimespan);
         return ScheduledTimespan;
    }
    

    Following function returns the delay time from current time of the day. If current time of the day passed the job run time, appropriate delay will be added to job run like below,

    private static TimeSpan getJobRunDelay()
    {
        TimeSpan scheduledParsedTime = getScheduledParsedTime();
        TimeSpan curentTimeOftheDay = TimeSpan.Parse(DateTime.Now.TimeOfDay.ToString("hh\\:mm"));
        TimeSpan delayTime = scheduledParsedTime >= curentTimeOftheDay
            ? scheduledParsedTime - curentTimeOftheDay     // Initial Run, when ETA is within 24 hours
            : new TimeSpan(24, 0, 0) - curentTimeOftheDay + scheduledParsedTime;   // For every other subsequent runs
        return delayTime;
    }
    

    use following overhead to achieve 24 hour delay after every execuion,

    _timer = new Timer(methodToExecute, null, getJobRunDelay(), new TimeSpan(24, 0, 0));
    

    timer will call the methodToExecute based on JobRunDelay everyday