It is necessary to carry out certain actions on the schedule, an abstract example:

  • on Monday at 12:00 take files from the folder
  • on Tuesday at 13:39 to create a folder with files
  • on the third Friday at 7:03 count the number of files

Is it advisable for this to use the timer with Interval per minute and in its Tick check the time and day of the week?

 private void timer1_Tick(object sender, EventArgs e) { var currentTime = DateTime.Now.TimeOfDay; var currentDow = DateTime.Now.DayOfWeek; var oneMinute = new TimeSpan(0, 1, 0); if ((currentDow == DayOfWeek.Monday)&&(currentTime-timeMonday<oneMinute)) { MondayOperation(); } if ((currentDow == DayOfWeek.Tuesday)&&(currentTime-timeTuesday<oneMinute)) { TuesdayOperation(); } if ((currentDow == DayOfWeek.Friday)&&(MyDoWInMonth(DateTime.Now).Equals(3))&(currentTime-timeFriday<oneMinute)) { FridayOperation(); } } 

    5 answers 5

    No, this is completely inadequate. Windows makes no guarantees that your timer will really be called every minute. With such comparisons, you can easily miss the right time or work twice.

    It will be more correct to store the following start time for each task and start the task when the current time is longer than the scheduled one (but did not go beyond a certain reasonable interval). About strict time comparisons forget in principle!


    PS for reference - my old answer to a related topic: https://ru.stackoverflow.com/a/593736/178779

      Better use the Quartz.net library, it is specifically designed for such purposes and is very flexible. It is also in nuget:

      Install-Package Quartz

      Or you can even use the Windows Task Scheduler.

        Hangfire - Task Scheduler for .NET

        In my opinion, this is the best multi-threaded and scalable task scheduler. Easy installation with NuGet

         Install-Package Hangfire 

        From the box there is a beautiful dashboard with all the statistics and all the planned tasks.

        Short review on habrahabr

          I would divide the program into 3 modules and use the standard Windows Task Scheduler. It will be more convenient to test + it is always clear which component works incorrectly

            You can look in the direction of TopShelf + Quartz , very convenient + there is everything you need (modules for DI, planning as you like).

            To do this, you will need to divide the work (create classes derived from IJob ), then describe the planning mechanism like this:

             private static void ScheduleRepeatableJobIn**<T>(ServiceConfigurator<Service> serviceConfigurator, int timeout) where T : IJob { serviceConfigurator.ScheduleQuartzJob(configurator => configurator.WithSimpleRepeatableSchedule<T>(TimeSpan.From**(timeout), typeof(T).Name)); } 

            And then just start the service / console like this:

              HostFactory.Run(x => { x.Service<Service1>(s => { ScheduleRepeatableJobInMinutes<Job1>(s, timeout); ScheduleRepeatableJobInMinutes<Job2>(s, timeout); s.WhenStarted(tc => tc.Start()); s.WhenStopped(tc => tc.Stop()); }); }); 

            PS The sample code is indicative. To solve your problem, you will need to write your own planning logic.