2012-02-09 16 views
7

? Recientemente me han desafiado a escribir un servicio de Windows. Necesitaba solicitar periódicamente una URL y verificar su disponibilidad. Para esto, decidí inicializar un temporizador en el método OnStart del servicio y hacer todo el trabajo en el evento timer_Tick.¿Por qué el servicio de Windows no funciona correctamente con System.Timers.Timer o System.Windows.Forms.Timer

Mi primer enfoque fue usar System.Windows.Forms.Timer y su evento Tick. Lo elegí por el tutorial que estaba leyendo. De alguna manera no pude hacer que el servicio funcione. Se instaló e inició sin problemas, pero no desencadenó el evento (adjunté el depurador al proceso y vi que no se había activado). Pensé que quizás usar el temporizador Forms en el servicio de Windows no es una buena idea, así que decidí cambiar a System.Timers.Timer y utilizar su evento Elapsed. Esto no funcionó bien. Probé ambos enfoques mencionados en una aplicación de Windows Forms y ambos funcionaron.

Después de excavar, encontré este sitio: http://weblogs.asp.net/sibrahim/archive/2004/01/13/58429.aspx en el que el blogger aconseja utilizar otro temporizador: System.Threading.Timer. Cambié el enfoque por tercera vez y BOOM comenzó a funcionar como un amuleto.

Mi pregunta es: ¿por qué no puedo usar los otros temporizadores en servicios de Windows y por qué es tan difícil encontrar información al respecto?

+1

Ahora encontré este artículo comparando diferentes temporizadores .NET. Definitivamente vale la pena leer: http://msdn.microsoft.com/en-us/magazine/cc164015.aspx –

+0

El 'System.Threading.Timer' es el único que funcionó para mí en' Windows Server 2008 R2' a través de Timers. Timer funcionó en mi 'portátil con Windows 7'. – Lijo

Respuesta

8

El temporizador System.Windows.Forms.Timer usa la bomba de mensajes de la interfaz de usuario para organizar el evento tick, un servicio no ejecuta un mensaje de bomba por defecto, así que sin un poco de trabajo adicional los temporizadores System.Windows.Forms.Timer no funcionarán.

El System.Timers.Timer es un temporizador basado en el servidor y provoca un evento en la cadena en la que lo creó (creo). Si esto no funciona, quizás no está iniciando el temporizador o el temporizador se ejecuta en un subproceso que termina inmediatamente (como en, nada mantiene el hilo vivo para que termine).

http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

El temporizador System.Threading.Timer utiliza una devolución de llamada que se ejecuta en un hilo ThreadPool y no está ligada a la bomba de mensajes en absoluto, por lo tanto, esto funcionó.

Cuando ejecuta Application.Run(myForm) en un proyecto de WinForms, esa llamada también ejecuta la bomba de mensajes, esto administra los mensajes de IU. El temporizador de Windows que menciona es un componente de interfaz de usuario y espera que la bomba de mensajes se ejecute para que el evento de marcación se produzca en el subproceso de interfaz de usuario.

Echa un vistazo aquí para el funcionamiento de una bomba de mensaje en un servicio de Windows:

Message pump in .NET Windows service

Más información:

http://support.microsoft.com/kb/842793

En conclusión, me acaba de ir con la System.Threading.Timer clase.

+2

Ambos temporizadores ejecutan código en una cadena de subprocesos. Hacer que el evento/devolución de llamada se ejecute en el mismo hilo que creó el temporizador requiere magia. El tipo de magia que proporciona una bomba de mensajes. –

Cuestiones relacionadas