views:

92

answers:

5

I'm writing a windows service that should perform an action every, lets say, 60 seconds.

How is the best way to implement that main loop?

Implementations I've seen so far:
1) Using a Timer object that executes a delegate every xx seconds
2) Using ManualResetEvents (the implementation I've seen only executes once, but as far as I understood, it is possible to create a loop with such resetevents)

The windows service will run all the time, so it would be best to create a service that has no memory leak.

What is the best way to implement that main loop?

Edit after comments: The action that will be performed every X seconds will start several (lets say max 10) threads. Each thread does not run longer than 30 seconds

+3  A: 

Use a Timer. This will make the intention of the program the most clear. It is easy to start and stop the timer from your OnStart and OnStop methods, and the callbacks will fire on the thread pool so you won't tie up a thread. The Timer object won't leak memory by itself. (You could still write a bug that leaks memory, but that's equally easy to do with any implementation of the main loop.)

Quartermeister
+1  A: 

If there is no chance that your action will not ever take longer than xx seconds I would just go with the timer. If not I would go with the ManualResetEvents. I assume you do not want more than one action to run concurrently.

Romain Hippeau
I edited my question to answer your question about running multiple actions at once.
citronas
+2  A: 

If you do use a system.timers.timer make sure to set autoreset to false and start it and the end of your process. Here's a full example

http://stackoverflow.com/questions/3266420/needed-a-windows-service-that-executes-jobs-from-a-job-queue-in-a-db-wanted-ex/3266671#3266671

Conrad Frix
+3  A: 

Consider using Quartz.net. I'm using this library and I'm very happy with it. You could set custom cron schedule that will suit your needs.

empi
+1  A: 

Here is another pretty common pattern using a ManualResetEvent as both a stopping and a throttling mechanism.

public class Example
{
  private Thread m_Thread;
  private ManualResetEvent m_StopSignal = new ManualResetEvent(false);

  public void Start()
  {
    m_Thread = new Thread(Run);
    m_Thread.Start();
  }

  public void Stop()
  {
    m_StopSignal.Set();
    if (!m_Thread.Join(MAX_WAIT_TIME))
    {
      m_Thread.Abort() // Abort as a last resort.
    }
  }

  private void Run()
  {
    while (!m_StopSignal.WaitOne(YOUR_INTERVAL))
    {
      // Your task goes here.
    }
  }
}
Brian Gideon
Should be `while (!m_StopSignal.WaitOne(YOUR_INTERVAL))` I guess.
Ben Voigt
Thanks. It is fixed.
Brian Gideon