12

I'm using a System.Timers.Timer and I've got code like the following in my OnStart method in a c# windows service.

timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Interval = 3600000;
timer.Start();

This causes the code in timer_Elapsed to be executed every hour starting from an hour after I start the service. Is there any way to get it to execute at the point at which I start the service and then every hour subsequently?

The method called by timer_Elapsed takes too long to run to call it directly from OnStart.

Andy
  • 7,428
  • 7
  • 43
  • 68

4 Answers4

20

Just start a threadpool thread to call the worker function, just like Timer does. Like this:

        timer.Elapsed += timer_Elapsed;
        ThreadPool.QueueUserWorkItem((_) => DoWork());
    ...

    void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
        DoWork();
    }

    void DoWork() {
        // etc...
    }
Hans Passant
  • 897,808
  • 140
  • 1,634
  • 2,455
2

If you want your Timer to be fired immediately then you could simply just initialize the Timer object without a specified interval (it will default to 100ms which is almost immediately :P), then set the interval within the called function to whatever you like. Here is an example of what I use in my Windows Service:

private static Timer _timer;

protected override void OnStart(string[] args)
{
    _timer = new Timer(); //This will set the default interval
    _timer.AutoReset = false;
    _timer.Elapsed = OnTimer;
    _timer.Start();
}

private void OnTimer(object sender, ElapsedEventArgs args)
{
    //Do some work here
    _timer.Stop();
    _timer.Interval = 3600000; //Set your new interval here
    _timer.Start();
}
John Odom
  • 1,135
  • 2
  • 19
  • 35
2

Use AutoReset Property of System.Timers.Timer and set it value to "true". No need to use timer.Start() because it does the same job as timer.Enabled = true;

timer = new Timer();
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Interval = 3600000;
timer.AutoReset = true;

AutoReset = true will set a value indicating that the Timer should raise the Elapsed event each time when the specified interval elapses.

1

Use System.Threading.Timer class instead of System.Timers.Timer as this type is just a wrapper for Threading Timer.

It also suits your requirement.

 System.Threading.Timer timer =
                new System.Threading.Timer(this.DoWork, this, 0, 36000);

Here are the details.

Vijay Sirigiri
  • 4,583
  • 28
  • 31
  • I did that but here at least did not worked. It runs the method just before the time is started but it runs inside the onStart(). – Thiago Jun 28 '12 at 19:25