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.Timertimer 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 theSystem.Windows.Forms.Timertimers will not work.The
System.Timers.Timeris 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.Timertimer uses a callback that runs on aThreadPoolthread 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.Timerclass.