2
\$\begingroup\$

I need to call a function exactly at certain hour, daily, my programs runs 24/7.

I wrote the following timer mechanism, which generally works that way:

  1. Calculate time until hour and generate timer with that interval.

  2. When timer elapse, call timer event and generate another 24h timer.

  3. Go back to step 2.

private static void InitTimeBasedTimer(TimeSpan timeToRun, Action funcToRun)
{
    TimeSpan interval = timeToRun.Subtract(DateTime.Now.TimeOfDay);
    double intervalMillis = interval.TotalMilliseconds;
    if (interval.TotalMilliseconds < 0)
    {
        intervalMillis = (new TimeSpan(24, 0, 0)).Add(interval).TotalMilliseconds;
    }
    Timer timer = new Timer(intervalMillis);
    timer.AutoReset = false;
    timer.Elapsed += (sender, e) => TimeBasedCallback(timeToRun, funcToRun);
    timer.Start();
}

public static void TimeBasedCallback(TimeSpan timeToRun, Action funcToRun)
{
    funcToRun();
    TimeSpan interval = timeToRun.Subtract(DateTime.Now.TimeOfDay); //24 h
    double intervalMillis = interval.TotalMilliseconds;
    if (intervalMillis < 0)
    {
        intervalMillis = (new TimeSpan(24, 0, 0)).Add(interval).TotalMilliseconds;
    }
    Timer timer = new Timer(intervalMillis);
    timer.AutoReset = false;
    timer.Elapsed += (sender, e) => TimeBasedCallback(timeToRun, funcToRun);
    timer.Start();
}

EDIT:
There are several functions that each writes to a DB every day in different hours. Can't afford task scheduler / process for each function. Quartz.NET seems a bit overkill for such a simple task.

\$\endgroup\$
  • 4
    \$\begingroup\$ For this kind of Task you should use something like the TaskScheduler of Windows of a library like Quartz.NET \$\endgroup\$ – Jehof Oct 29 '13 at 8:36
  • \$\begingroup\$ I need several functions that each writes to a DB every day in different hours. Can't afford task / process for each function. Quartz.NET seems a bit overkill for such a simple task. \$\endgroup\$ – Ofiris Oct 29 '13 at 9:40
4
\$\begingroup\$

Without knowing what you're trying to do, I'd say this is the wrong approach. I would create an executable and set it up as a scheduled task to run every 24 hours.

Not sure what OS you are using, but assuming it's windows its fairly easy http://windows.microsoft.com/en-au/windows7/schedule-a-task

\$\endgroup\$
2
\$\begingroup\$

Agree with another answer. Trying to write your own scheduler is a wrong approach 99% of the time.

Have you thought about these situations?

  1. What happens if your 'funcToRun' function throws an exception? Not only you will not setup the next timer, but depending upon how other things are setup, it will bring down your main program.

  2. Let's say you will set up a try/catch around 'funcToRun' so that you can run it during the next scheduled time. How would you know if it's okie to run it again? What if the user wants to kick off the process manually immediately after fixing the problem which caused the failure?

  3. What if user wants to change the time when the process runs? In your case, you will have to change the code and deploy it before the changes take effect.

  4. What if certain process requires higher privileges so that it can access certain network resource? In your design, you will have to give your main process higher privileges.

  5. What happens if 'funcToRun' itself runs for more than 24 hours?

  6. How can you specify that a given funcToRun should run for maximum of 1 hour?

  7. How would you account for Daylight Savings Time? Let's say your process is supposed to run at 5pm. If you were to use Task Scheduler, it will automatically run at 5pm accounting for the DST, your code will be off by hours adjusted by DST.

I could go on and on. Do yourself a favor and go to Task Scheduler in Windows and look at the 'Create Task' dialog. Go through all the options. These are the things you will run into eventually whenever you try to design a scheduler system. Instead of trying to re-create Task Scheduler, why not use it?

\$\endgroup\$
-1
\$\begingroup\$

You can use a timer. Also you can do this:

 public Form1()
    {
        InitializeComponent();
        DateTime today = DateTime.Today;
        StreamDate(today)
        timer1.Start();
    }
private void timer1_Tick(object sender, EventArgs e)
    {
        DateTime today = DateTime.Today;
        string text = System.IO.File.ReadAllText(@"C:\date.txt");
        DateTime newdate = Convert.ToDateTime(text);
        if (today != newdate)
        {
          StreamDate(today)

        }
private void StreamDate(string today)
{
            StreamWriter foldcreat = new StreamWriter(@"C:\date.txt");
            foldcreat.WriteLine(String.Format("{0}", today));
            foldcreat.Close();
}

it's if you have oportunity to create text file .... Another way : http://www.codeproject.com/Articles/6507/NET-Scheduled-Timer

\$\endgroup\$
  • 2
    \$\begingroup\$ This hasn't very much in common to the question itself. Why do you need a Form ? \$\endgroup\$ – Heslacher Dec 7 '15 at 11:14
  • 1
    \$\begingroup\$ Please review the code, rather than providing your solution to the same problem. \$\endgroup\$ – Fund Monica's Lawsuit Dec 7 '15 at 17:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.