2

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?

Habeeb
  • 7,601
  • 1
  • 30
  • 33
Damn Vegetables
  • 11,484
  • 13
  • 80
  • 135
  • Possible duplicate of [this](https://stackoverflow.com/questions/391621/compare-using-thread-sleep-and-timer-for-delayed-execution) SO question. – Jeroen Heier Nov 13 '17 at 05:06

1 Answers1

4

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();
Habeeb
  • 7,601
  • 1
  • 30
  • 33
  • 1
    Wouldn't the proper cron expression here be `* 0/5 10-19 * * MON-FRI`? – Rytmis Nov 13 '17 at 05:08
  • 1
    I am new to Quartz.NET but the codes seem to be called on everyday. Is it excluding Saturday and Sunday? EDIT: Rytmis' expression seems to exclude Saturday/Sunday, but is it possible with the trigger code as in your second option? – Damn Vegetables Nov 13 '17 at 05:08
  • Very true. I overlooked the weekends. :) I ll update the answer. – Habeeb Nov 13 '17 at 06:30
  • I tried this: ITrigger trigger = TriggerBuilder.Create() .WithIdentity("trigger1", "group1") .WithCronSchedule("* 0/5 10-19 * * MON-FRI") .Build(); but `System.FormatException: 'Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.'` happened. – Damn Vegetables Nov 13 '17 at 06:33
  • 1
    I have found '.OnMondayThroughFriday()', and attached it between EndingDailyAt and WithInterval... – Damn Vegetables Nov 13 '17 at 06:49
  • Is it possible to start the job right ahead and then measure 5 minutes from that moment? Currently, I run the code above with `.StartNow()`, but it seemed that the execution starts when the minute is a multiple of the interval in that day . I mean, the debug message was something like, `Scheduled at 13/11/2017 16:15:36 Executed at 13/11/2017 16:20:00 Executed at 13/11/2017 16:25:00 ...` Is it possible to make the first execution at 16:15:36 and then 16:20:36, etc? – Damn Vegetables Nov 13 '17 at 07:17