5

I am writing a program that will perform an operation every 10 or 15 minutes. I want it to be running all the time, so I need something that is cheap on processing power. What I have read so far seems to suggest that I want to use a Timer. Here is a clip of the code I have so far.

class Program {
    private static Timer timer = new Timer();

    static void Main(string[] args) {
        timer.Elapsed += new ElapsedEventHandler(DoSomething);
        while(true) {
            timer.Interval = TimerMilliseconds(); // The duration of the wait will differ each time
            timer.Enabled=true;
        }
    }
}

The problem here is that the while loop just keeps executing rapidly. How do I halt execution until the timer is elapsed. My program really doesn't need to be multi threaded. Is a Timer the right tool for this job?

Thank you in advance for any help!

UPDATE: Sorry for the confusion. I have implemented the DoSomething method. I just did not include it as I don't believe it is part of my issue.

Joe
  • 800
  • 4
  • 10
  • 26

6 Answers6

4

Timer's will fire off the Elapsed event once the specified interval has elapsed.

I would do something like this:

private static Timer timer = new Timer();

static void Main(string[] args) 
{
    timer.Elapsed += new ElapsedEventHandler(DoSomething);
    timer.Interval = TimerMilliseconds(); // The duration of the wait will differ each time
    timer.Enabled=true;

    Console.ReadKey(); //Wait for keypress to terminate
}

You could also implement this as a service so you don't have to have a blocking call like Console.ReadKey to keep the program from terminating.

Finally, you could just change the interval in the event handler:

static void DoSomething(...)
{
   timer.Stop();
   timer.Interval = TimerMilliseconds();

   ...
   timer.Start();
}
BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • This looks like what I want. I am using System.Timers.Timer. Do I need to manually stop the timer? I believe it stops automatically if AutoReset parameter is not set? – Joe Jan 07 '15 at 20:54
  • 1
    @Joe You don't *have* to stop it, but if the process is long running, and the timer interval short, you could have two executing at the same time. Its up to you, and you could probably get away without it. – BradleyDotNET Jan 07 '15 at 20:57
2

The problem with this code is that you're using a loop to set the Interval and Enabled properties of the Timer, which will execute said assignments over and over - it's not waiting for the timer to execute in some way.

If your application doesn't need to be mutlithreaded, then you might be better simply calling Thread.Sleep between executions.

class Program {    
    static void Main(string[] args) {
        while(true) {
            Thread.sleep(TimerMilliseconds()); // The duration of the wait will differ each time
            DoSomething();
        }
    }
}
David
  • 10,458
  • 1
  • 28
  • 40
2

take out the timer and loop from your logic. Just use windows scheduler to execute your program after 15 minutes. Or you can use windows services. Please read Best Timer for using in a Windows service

Community
  • 1
  • 1
ATHER
  • 3,254
  • 5
  • 40
  • 63
1

remove the while loop completely.

inside of the DoSomething() function (once implemented) stop timer at start and at the end reset the interval before restarting the timer.

Buck3y3
  • 136
  • 8
0

I guess the comments and answrs already provide the hints you need, but the MSDN docs for Timer actually provide a nice example. In my opinion the Timer approach is a bit tidier, it's easier to read your intentions and abstracts away the details of invoking your scheduled code.

Fasermaler
  • 943
  • 6
  • 14
0

Here's another alternative approach using ManualResetEvent and WaitOne(). This will allow you to halt the main thread without worrying about it being killed accidentally by an errant keypress. You can also Set() the MRE when certain conditions are met to allow the app to exit gracefully:

class Program
{

    private static Timer timer;
    private static ManualResetEvent mre = new ManualResetEvent(false);

    static void Main(string[] args)
    {
        timer = new Timer(TimerCallback, null, 0, (int)TimeSpan.FromMinutes(15).TotalMilliseconds);
        mre.WaitOne();
    }

    private static void TimerCallback(object state)
    {
        // ... do something in here ...
        Console.WriteLine("Something done at " + DateTime.Now.ToString());
    }

}
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40