views:

1807

answers:

6

I'm writing a windows service that needs to sleep for long periods of time (15 hrs is the longest it will sleep, 30 mins is the shortest). I'm currently using Thread.Sleep(calculatedTime) to put my code into sleep mode. Is Thread.Sleep the best option or should I be using a timer? I've been googling this for a while and can't find a concise answer. Since this is a windows service, I don't have to worry about locking the UI, so I can't think of a reason not to use Thread.Sleep.

Any insight would be appreciated.

+11  A: 

I would use a timer, Thread.Sleep, could cause a blocking piece that could prevent the service from shutting down.

If the interval is that wide spread, and regular, you might just schedule it as well. But if you are talking about long, non-consistent intervals, then yes a Timer would be better.

Mitchel Sellers
+6  A: 

It's generally regarded as bad practice to use Thread.Sleep() in a lot of cases.

If you want the service to run in the background, you should use a timer.

If the service only needs to be run at scheduled intervals, I'd recommend you look into using Windows task scheduler to allow Windows to run the application when you need it to.

Dan Herbert
+2  A: 

You should not pre-calculate such large amounts of time and sleep for hours. Sleep for a minute at best, then wake up and re-calculate the time, sleep again for no more that a minute. I assume the calculation is very cheap or it can be made very cheap with caching. The problem my advise is trying to mitigate is that computer clocks are surprisingly 'jumpy', mostly due to time drift corrected by network time service, also because of daylights savings and not least because user adjusting the clock. So is better to constantly recompute the time for such long intervals, even if it means waking up every minute or so. And don't be surprised (ie. don't assert) if you wake up in the 'past', clocks can adjust back in time.

Remus Rusanu
+1  A: 

Another thing to consider is that threads are finite resources and each thread consumes a portion of memory (1MB?) for the its stack. They may also increase load for the scheduler.

Now, if your service isn't doing much else the wasted space is trivial, but it is wise to be aware of this before you start allocating multiple threads. Using a ThreadPool and/or Timers is much more efficient.

Kevin Pullin
+4  A: 

Since a service may be asked to stop at any time by the Service Control Manager, your thread should always be ready to respond to these requests, so you should not use Thread.Sleep(). Instead, create a manual-reset event in the main thread and use its WaitOne method with a timeout in your worker thread. WaitOne will return false when the time expires.

When your service class's OnStop or OnShutdown methods are called, set the event and that will cause WaitOne to return true and you can then exit your worker thread.

Carlos A. Ibarra
A: 

I use sleep instead of a timer and I let the service do power naps of 500ms, just like Remus suggests. When the time is up the action is executed and the next wake up call is calculated. It works fine but apparently I have a problem when installing the service on a Win2008-server. It seems that the loop is executed only once. Whether this has to do with sleep versus timer, I don't know yet.

henrik carlsen