Introduction
This article aims to solve the scheduling problem within an application.
We all know the simple scenario where we need to write something which needs to run every X time. The solution in this case is easy – Timer. You give it the iteration time (let's say 5 minutes), set up the event handler so every 5 minutes it will fire and you are done.
The case gets trickier when you are asked to run your application every X time starting from Y. In this case, you need someone/something to know when to start (usually less than X time from now) and then to keep track of the iterations.
Background
My need for this solution came from a need to run a Windows service which will do some DB executions every 24 hours at 03:00. The new application came to replace a SQL-server job which was basically doing the same thing, only this time we had to run the application elsewhere.
Using the Code
The use is very easy and looks very similar to the use we usually have with the Timer
control:
DateTime start = System.DateTime.Now.AddMinutes(1);
Scheduler.PeriodicSchedules scheduler =
new Scheduler.PeriodicSchedules
(start,Scheduler.PeriodicSchedules.ExecutionType.Minutely);
scheduler.Elapsed+=new System.Timers.ElapsedEventHandler(scheduler_Elapsed);
scheduler.Enabled = true;
As you can see, the PeriodicSchedules
constructor gets a DateTime
object representing the time it should run the first time and ExecutionType
enumerator representing the interval.
The enumerator can be extended easily to any interval you might want.
Points of Interest
I was using the ICurrentTime interface
in order to enable unit tests for the application. This way, I can inject the CurrentTime
of the machine from the outside instead of playing with the local clock in order to test different scenarios:
public interface ICurrentTime
{
DateTime GetCurrentDateTime();
}
And while testing:
public class CurrentTime:ICurrentTime
{
DateTime currentTime;
public CurrentTime(DateTime mynow)
{
currentTime = mynow;
}
public DateTime GetCurrentDateTime()
{
return currentTime;
}
}
[Test]
public void OneHourEarlierInterval()
{
CurrentTime now = new CurrentTime(new DateTime(2007, 5, 30, 15, 0, 0));
Scheduler.PeriodicSchedules scheduler =
new Scheduler.PeriodicSchedules(14, 0, 0,
Scheduler.PeriodicSchedules.ExecutionType.Hourly, now);
Console.WriteLine(scheduler.Interval.ToString());
Assert.AreEqual((double)(60000 * 60), scheduler.Interval);
}
History
- 2nd June, 2007: Initial post