Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# - Alternative to System.Timers.Timer, to call a function at a specific time

I want to call a specific function on my C# application at a specific time. At first I thought about using a Timer (System.Time.Timer), but that soon became impossible to use. Why?

Simple. The Timer class requires a Interval in milliseconds, but considering that I might want the function to be executed, let's says in a week that would mean:

  • 7 days = 168 hours;
  • 168 hours = 10,080 minutes;
  • 10,080 minutes = 604,800 seconds;
  • 604,800 seconds = 604,800,000 milliseconds;
  • So the interval would be 604,800,000;

Now let's remember that the Interval accepted data type is int, and as we know int range goes from -2,147,483,648 to 2,147,483,647.

That makes Timer useless, not in this case, but in the case of more than about 25 days, once we cannot set a Interval bigger that 2,147,483,647 milliseconds.


So I need a solution where I could specify when the function should be called. Something like this:

solution.ExecuteAt = "30-04-2010 15:10:00";
solution.Function = "functionName";
solution.Start();

So when the System Time would reach "30-04-2010 15:10:00" the function would be executed in the application.

How can this problem be solved?


Additional information: What will these functions do?

  • Getting climate information and based on that information:
  • Starting / Shutting down other applications (most of them console based);
  • Sending custom commands to those console applications;
  • Power down, rebooting, sleep, hibernate the computer;
  • And if possible schedule the BIOS to power up the computer;

EDIT:

It would seem that the Interval accepted data type is double, however if you set a value bigger that an int to the Interval, and call Start() it throws a exception [0, Int32.MaxValue].

EDIT 2:

Jørn Schou-Rode suggested using Ncron to handle the scheduling tasks, and at first look this seems a good solution, but I would like to hear about some who has worked with it.

like image 412
Fábio Antunes Avatar asked Apr 23 '10 14:04

Fábio Antunes


3 Answers

Your "Start()" method should spawn a thread that wakes up at a defined interval, checks the time, and if you haven't reached the desired time, goes back to sleep.

like image 196
Adrian Avatar answered Oct 31 '22 07:10

Adrian


I would recommend that you just write a program that deals with the business part of it and then execute that program when necessary by using Windows Task Scheduler.

like image 23
Klaus Byskov Pedersen Avatar answered Oct 31 '22 07:10

Klaus Byskov Pedersen


One approach to task scheduling, simliar to that proposed by klausbyskov, is to built your scheduling service on top of an existing .NET scheduling framework/library. Compared to using the Windows Task Scheduler, this has the advantages of (a) allowing several jobs to be defined in the same project and (b) keeping jobs and scheduling logic "together" - i.e. not relying on server settings prone to get lost in system upgrades/replacements.

I know of two open-source projects that offer this kind of functionality:

  • "Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems." I have never actually used this framework myself, but from studying the website, I have the impression of a very solid tool, providing many cool features. The fact that there [quartz-net] tag on Stackoverflow might also indicate that it is actually used in the wild.

  • "NCron is a light-weight library for building and deploying scheduled background jobs on the .NET server platform." It does not have half as many features as Quartz.NET, and it does not have any tag on Stackoverflow, but the author (yours truly) believes that its low-friction API makes it somewhat easier to get started with.

Building your scheduling service on top of NCron, you can schedule a CleanupJob for weekly execution using a single line of code:

service.Weekly().Run<CleanupJob>();

Ok, you will need around three lines of boiler plate code on top of that to actually turn your project into a Windows service, but it sounds more impressive when I claim that it can be done with one line of code ;)

like image 43
Jørn Schou-Rode Avatar answered Oct 31 '22 08:10

Jørn Schou-Rode