Search code examples
c#scheduled-tasksquartz-schedulerschedulerquartz.net

Invoke a method every 5 minutes during working hours/days - Quartz.net


In short, I want to invoke a method at each 5 minutes, but only during the working time. At first I was trying to use Thread.Sleep() and at each invocation, I tried to calculate the amount of sleep time. Somehow, it did not work very well.

Here is the code that calculates the time for sleep.

    void Main()
    {
       while(true)
       {
         Work()
         Thread.Sleep(GetSleepTime());
       }
    }

    int GetSleepTime()
    {
        int time = 0;
        var now = DateTime.Now;
        var isWorkingTime = false;

        switch (now.DayOfWeek)
        {
            case DayOfWeek.Saturday:
            case DayOfWeek.Sunday:
                break;
            default:
                if (now.Hour >= 10 && now.Hour <= 19)
                {
                    time = 5 * 60 * 1000;
                    isWorkingTime = true;
                }
                break;
        }

        if (!isWorkingTime)
        {
            int remainingDays = 1;
            switch (now.DayOfWeek)
            {
                case DayOfWeek.Friday:
                    remainingDays = 3;
                    break;
                case DayOfWeek.Saturday:
                    remainingDays = 2;
                    break;
            }

            DateTime nextWorkingday = now.AddDays(remainingDays).Date;
            DateTime nextWorkingday10 = nextWorkingday.AddHours(10);
            time = (int)(nextWorkingday10 - now).TotalMilliseconds;
        }

        return time;
    }

Is this a suitable thing to use Quartz.NET for? If so, how can I do the same thing with it?


Solution

  • You need not use sleep. Quartz.net is intended to take care of the scheduling part. You need to create a job and its trigger.

    * 0/5 9,17 * * MON-FRI
    

    The above trigger will execute the job every 5 minutes from 9AM to 5PM

    Below is an alternate Option:

    If you are using v2+, you can use the following trigger definition from within the code.

    ITrigger trigger = TriggerBuilder.Create()
        .WithIdentity("trigger1", "group1")
        .WithDailyTimeIntervalSchedule(
            x => x.StartingDailyAt(TimeOfDay.HourAndMinuteOfDay(9, 0))
                     .EndingDailyAt(TimeOfDay.HourAndMinuteOfDay(17, 0))
                     .OnMondayThroughFriday()
                     .WithIntervalInMinutes(5))
        .Build();