I have been recently challenged with writing a Windows Service. I needed to periodically request a URL and check its availability. For this I decided to initialize a timer in OnStart
method of the service and do all the work in timer_Tick
event.
My first approach was using System.Windows.Forms.Timer
and its Tick
event. I chose for it, because of the tutorial that I was reading. Somehow I could not make the service work. It installed and started without problems, but it would not fire the event (I attached the debugger to the process and saw that it was not fired). I thought that maybe using Forms timer in Windows service is not a good idea, so I decided to switch to System.Timers.Timer
and utilize its Elapsed
event. This did not work either. I tried both mentioned approaches in a Windows Forms application and they both worked.
After some digging, I found this site: http://weblogs.asp.net/sibrahim/archive/2004/01/13/58429.aspx on which the blogger advices to utilize yet another timer: System.Threading.Timer
. I changed the approach for the third time and BOOM it started working like a charm.
My question is: why can't I use the other timers in Windows services and why is it so difficult to find an information about it?
The System.Windows.Forms.Timer
timer uses the message pump of the UI to marshal the tick event, a service doesn't run a message pump by default so without a little extra work the System.Windows.Forms.Timer
timers will not work.
The System.Timers.Timer
is a server-based timer and raises an event on the thread you create it on (I think). If this isn't working, perhaps you aren't starting the timer or the timer runs on a thread that immediately ends (as in, nothing is keeping the thread alive so it finishes).
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
The System.Threading.Timer
timer uses a callback that runs on a ThreadPool
thread and isn't tied to the message pump at all, hence this worked.
When you run Application.Run(myForm)
in a WinForms project, that call also runs up the message pump, this manages UI messages. The windows timer you mention is a UI component and expects the message pump to be running in order to cause the tick event to occur on the UI thread.
Take a look here for running a message pump in a Windows Service:
Message pump in .NET Windows service
Further reading:
http://support.microsoft.com/kb/842793
In conclusion, I'd just go with the System.Threading.Timer
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With