2009-06-15 7 views
12

Estoy escribiendo un servicio de Windows que necesita dormir durante largos períodos de tiempo (15 horas es la duración más larga, 30 minutos es la más corta). Actualmente estoy usando Thread.Sleep (calculateTime) para poner mi código en modo de suspensión. ¿Es Thread.Sleep la mejor opción o debería usar un temporizador? He estado buscando en Google por un tiempo y no puedo encontrar una respuesta concisa. Como este es un servicio de Windows, no tengo que preocuparme por bloquear la UI, así que no puedo pensar en una razón para no usar Thread.Sleep.Uso de Thread.Sleep() en un servicio de Windows

Cualquier apreciación sería apreciada.

Respuesta

19

Usaría un temporizador, Thread.Sleep, podría causar una pieza de bloqueo que podría evitar el apagado del servicio.

Si el intervalo es tan amplio y regular, puede programarlo también. Pero si estás hablando de intervalos largos, no consistentes, entonces sí, un Temporizador sería mejor.

7

En general, se considera una mala práctica el uso de Thread.Sleep() en muchos casos.

Si desea que el servicio se ejecute en segundo plano, debe usar un temporizador.

Si el servicio solo necesita ejecutarse a intervalos programados, le recomiendo que consulte el uso del programador de tareas de Windows para permitir que Windows ejecute la aplicación cuando la necesite.

5

No debe precalcular esas grandes cantidades de tiempo y dormir durante horas. Duerme un minuto en el mejor de los casos, luego despierta y vuelve a calcular el tiempo, duerme otra vez por no más de un minuto. Supongo que el cálculo es muy barato o puede hacerse muy barato con el almacenamiento en caché. El problema que mi consejo está tratando de mitigar es que los relojes de la computadora están sorprendentemente 'saltones', principalmente debido a la deriva de tiempo corregida por el servicio de tiempo de red, también debido a los ahorros de luz diurna y no menos importante porque el usuario ajusta el reloj. Por lo tanto, es mejor recalcular constantemente el tiempo para intervalos tan largos, incluso si eso significa despertarse cada minuto más o menos. Y no se sorprenda (es decir, no afirme) si se despierta en el "pasado", los relojes pueden ajustarse en el tiempo.

1

Otra cosa a considerar es que los hilos son recursos finitos y cada hilo consume una parte de la memoria (1MB?) Para su pila. También pueden aumentar la carga del planificador.

Ahora, si su servicio no está haciendo mucho más, el espacio desperdiciado es trivial, pero es prudente tenerlo en cuenta antes de comenzar a asignar varios subprocesos. Usar ThreadPool y/o Timers es mucho más eficiente.

9

Dado que es posible que el Administrador de control de servicios detenga un servicio, su hilo siempre debe estar listo para responder a estas solicitudes, por lo que no debe usar Thread.Sleep(). En su lugar, cree un evento de restablecimiento manual en el hilo principal y use su método WaitOne con un tiempo de espera en su hilo de trabajo. WaitOne devolverá falso cuando expire el tiempo.

Cuando se invocan los métodos OnStop o OnShutdown de su clase de servicio, configure el evento y esto hará que WaitOne devuelva verdadero y luego podrá salir de su hilo de trabajo.

Cuestiones relacionadas