I have on occasion needed to schedule a process to run on a nightly basis, but I did not have access to the server where I could schedule a windows service. So I had to turn to using a timer object in ASP.NET to schedule the process for me.
I used the application_start method (in the global.asax) to start the timer, so that when the app stops, the schedule will start again the next time the app re-starts. The problem that I ran into though, is that I have no control over when the application starts and stops. I had to have the schedule run at a specified time each night. I came up with a couple of methods that allow me to determine what the time is currently, pass in the time I want the process to start and then pass in the interval I want to have the process repeated.
My example below uses 6:30 pm as an initial start time, with the process repeating every 24 hours. Note that all times must be calculated in milliseconds.
runat=”server”>
private void NightlyProcess(object o)
{
//write code to be processed at specified intervals
}
void Application_Start(object sender, EventArgs e)
{
System.Threading.TimerCallback tcb = new System.Threading.TimerCallback(NightlyProcess);
System.Threading.Timer theTimer = new System.Threading.Timer(tcb, null, GetTimerInitialDelay(18,30), GetTimerRepeatDelay(24));
}
///
/// Use this function to determine what the initial delay should be so that processing can happen
/// nightly at the time you determine
/// instead of at the time the web application restarted
///
///
private long GetTimerInitialDelay(int hours, int minutes)
{
long startMS, repeatMS, currentMS;
//1000 = milliseconds per second
//60 = seconds per minute
//60 = minutes per hour
//hours = based on 24 hour clock — this example passes in 18 to signify 6pm
//minutes = if you want to have the process happen at a time other than on the hour
//this example passes 18 and 30 so the first run will happen at 6:30 pm
startMS = (1000 * 60 * 60 * hours) + (1000 * 60 * minutes);
repeatMS = GetTimerRepeatDelay(24);
DateTime now = DateTime.Now;
long currentHours = 1000 * 60 * 60 * now.Hour;
long currentMinutes = 1000 * 60 * now.Minute;
long currentSeconds = 1000 * now.Second;
long currentMilliSeconds = now.Millisecond;
currentMS = currentHours + currentMinutes + currentSeconds + currentMilliSeconds;
long delay = startMS – currentMS;
// we have to wait until the next appropriate time to run code
// if it is after the specified time (after 6:30pm in our case)
// we need to take the repeatDelay time (24 hours) and add our initial delay to it (it will be a negative number)
// this will ensure that the process will not run until 6:30pm tomorrow
// otherwise, we just wait the regular delay and the process will start at 6:30pm today
if (delay return repeatMS + delay;
}
else
{
return delay;
}
}
private long GetTimerRepeatDelay(int hours)
{
long repeatMS;
//1000 = milliseconds per second
//60 = seconds per minute
//60 = minutes per hour
//hours = based on 24 hour clock — this example passes in 24 so it will repeat once per day
repeatMS = 1000 * 60 * 60 * hours;
return repeatMS;
}
Categories: Web
Leave a Reply