Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
804 views
in Technique[技术] by (71.8m points)

.net - Why doesn't Windows Service work properly with System.Timers.Timer or System.Windows.Forms.Timer

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...