How can I schedule a C # Windows service to perform a task daily?

I have a service written in C # (.NET 1.1), and I want it to perform some cleaning action at midnight every night. I have to store all the code contained in the service, and what is the easiest way to do this? Use Thread.Sleep() and check leap time?

+75
c # scheduled-tasks scheduling windows-services
Feb 02 '09 at 15:21
source share
10 answers

I would not use Thread.Sleep (). Either use the scheduled task (as others have indicated), or set a timer inside your service that works periodically (for example, every 10 minutes) and checks if the date has changed since the last launch:

 private Timer _timer; private DateTime _lastRun = DateTime.Now.AddDays(-1); protected override void OnStart(string[] args) { _timer = new Timer(10 * 60 * 1000); // every 10 minutes _timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); _timer.Start(); //... } private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { // ignore the time, just compare the date if (_lastRun.Date < DateTime.Now.Date) { // stop the timer while we are running the cleanup task _timer.Stop(); // // do cleanup stuff // _lastRun = DateTime.Now; _timer.Start(); } } 
+82
02 Feb '09 at 15:31
source share

Check out Quartz.NET . You can use it in a windows service. It allows you to run a task based on a customized schedule and even supports the simple cron job syntax. I had a great success.

Here is a brief example of its use:

 // Instantiate the Quartz.NET scheduler var schedulerFactory = new StdSchedulerFactory(); var scheduler = schedulerFactory.GetScheduler(); // Instantiate the JobDetail object passing in the type of your // custom job class. Your class merely needs to implement a simple // interface with a single method called "Execute". var job = new JobDetail("job1", "group1", typeof(MyJobClass)); // Instantiate a trigger using the basic cron syntax. // This tells it to run at 1AM every Monday - Friday. var trigger = new CronTrigger( "trigger1", "group1", "job1", "group1", "0 0 1 ? * MON-FRI"); // Add the job to the scheduler scheduler.AddJob(job, true); scheduler.ScheduleJob(trigger); 
+69
Feb 02 '09 at 15:28
source share

Daily challenge? It seems like it should be a scheduled task (control panel) - there is no need for maintenance here.

+19
Feb 02 '09 at 15:27
source share

Should it be an actual service? Can you just use the built-in scheduled tasks in the Windows Control Panel.

+15
Feb 02 '09 at 15:26
source share

The way I do this is a timer.

Start the server timer, check it hour / minute every 60 seconds.

If this is the correct hour / minute, start the process.

This is actually abstracted into the base class, which I call OnceADayRunner.

Let me clear the code a bit and I will post it here.

  private void OnceADayRunnerTimer_Elapsed(object sender, ElapsedEventArgs e) { using (NDC.Push(GetType().Name)) { try { log.DebugFormat("Checking if it time to process at: {0}", e.SignalTime); log.DebugFormat("IsTestMode: {0}", IsTestMode); if ((e.SignalTime.Minute == MinuteToCheck && e.SignalTime.Hour == HourToCheck) || IsTestMode) { log.InfoFormat("Processing at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute); OnceADayTimer.Enabled = false; OnceADayMethod(); OnceADayTimer.Enabled = true; IsTestMode = false; } else { log.DebugFormat("Not correct time at: Hour = {0} - Minute = {1}", e.SignalTime.Hour, e.SignalTime.Minute); } } catch (Exception ex) { OnceADayTimer.Enabled = true; log.Error(ex.ToString()); } OnceADayTimer.Start(); } } 

The beef method is in the e.SignalTime.Minute / Hour check.

There are hooks for testing, etc., but that’s what your past timer might look like so that it all works.

+3
02 Feb '09 at 15:26
source share

As others have already written, a timer is the best option in the scenario you describe.

Depending on your exact requirements, checking the current time every minute may not be necessary. If you do not need to perform the action exactly at midnight, but only an hour after midnight, you can go to Martin's approach , only checking if the date has changed.

If the reason you want to complete your action at midnight is because you expect a low load on your computer, take better care: the same assumption is often made by others, and suddenly you have 100 cleanup actions starting between 0: 00 and 0:01 in the morning

In this case, you should consider starting cleaning at another time. Usually I do this not for hours, but for half an hour (1.30 m., I am my personal preference).

+2
Feb 02 '09 at 17:02
source share

I would suggest that you use a timer, but set it to check every 45 seconds, not minutes. Otherwise, you may encounter situations where with a heavy load a check for a specific minute is skipped, because between the time the timer starts and the time that your code starts, and checks the current time, you may have missed the target minute.

+1
Feb 02 '09 at 15:36
source share

You can also try TaskSchedulerLibrary here http://visualstudiogallery.msdn.microsoft.com/a4a4f042-ffd3-42f2-a689-290ec13011f8

Deploy the AbstractScheduledTask abstract class and call the static ScheduleUtilityFactory.AddScheduleTaskToBatch method

0
Mar 03 '14 at 2:56
source share

Here is my piece of code that works:

  protected override void OnStart(string[] args) { timer = new Timer(); //Initialize the globally declared timer //SETTING THE INTERVAL FROM CONFIG FILE (10 SECONDS) timer.Interval = Convert.ToInt32(ConfigurationManager.AppSettings["TimerInterval"]); timer.Enabled = true; timer.Elapsed += timer_Elapsed; } 

In a past event, you can do this:

 private void timer_Elapsed(object sender, ElapsedEventArgs e) { timer.Enabled = false; string ScheduleTime = GlobalVariables.ScheduledTime;//GETTING SCHEDULED TIME FROM CONFIG IN (HH:mm) FORMAT string CurrentHourMin = DateTime.Now.ToString("HH:mm");//GETTING CURRENT TIME IN HH:mm format if (ScheduleTime == CurrentHourMin) { // YOUR CODE } System.Threading.Thread.Sleep(60000); //Putting thread to sleep for 60 seconds to skip the current minute to avoid re-execution of code timer.Enabled = true; } 
0
Dec 31 '15 at 8:09
source share

Try the following:

 public partial class Service : ServiceBase { private Timer timer; public Service() { InitializeComponent(); } protected override void OnStart(string[] args) { SetTimer(); } private void SetTimer() { if (timer == null) { timer = new Timer(); timer.AutoReset = true; timer.Interval = 60000 * Convert.ToDouble(ConfigurationManager.AppSettings["IntervalMinutes"]); timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); timer.Start(); } } private void timer_Elapsed(object source, System.Timers.ElapsedEventArgs e) { //Do some thing logic here } protected override void OnStop() { // disposed all service objects } } 
-one
Aug 09 '13 at 14:11
source share



All Articles