1

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

citronas
  • 19,035
  • 27
  • 96
  • 164
  • How much precision are you looking for? If one iteration takes longer than expected should the next iteration wait to begin? – ChaosPandion Jul 25 '10 at 17:08

5 Answers5

3

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
  • 57,579
  • 7
  • 124
  • 111
3

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
  • 15,755
  • 8
  • 62
  • 78
2

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

Needed: A Windows Service That Executes Jobs from a Job Queue in a DB; Wanted: Example Code

Community
  • 1
  • 1
Conrad Frix
  • 51,984
  • 12
  • 96
  • 155
1

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
  • 24,113
  • 5
  • 60
  • 79
1

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
  • 47,849
  • 13
  • 107
  • 150