2008-10-22 26 views
9

¿Puede alguien indicarme la forma más fácil de tener un temporizador en un servicio Win32?Temporizador en un servicio win32

Supongo que podría crear una ventana ficticia para este propósito o tener un segundo hilo, pero ¿qué es lo mejor? ¿Hay una manera más elegante?

Gracias de antemano.

Respuesta

1

Puede usar SetTimer para configurar el temporizador, luego tomar el mensaje WM_TIMER en su ciclo de mensajes.

Ejemplo:

// Establecer un temporizador expira en 10 segundos

SetTimer (hwnd, IDT_TIMER1, 10000, (TimerProc) NULL);

... a continuación, en el mensaje de bucle:

interruptor (WParam)

{ 

    case IDT_TIMER1: 

     // Boom goes the dynamite 

También puede decleare una función del tipo y TimerProc haya que llamar cuando el temporizador expira, si no' Quiero hacer el manejo del bucle de mensajes.

+1

+1 para "boom goes the dinamita", pero trabaje un poco en su formateo –

+0

Gracias - aunque no hay un bucle de mensaje en mi servicio para captar el mensaje :) – dennisV

+0

¡Así que cree uno! La cola de mensajes está configurada por el sistema operativo una vez que llamas a :: GetMessage o :: PeekMessage. –

3

Puede enviar sus mensajes principales de WM_TIMER. El lParam para el mensaje es la dirección de una función de devolución de llamada, o puede dejarlo NULO y manejarlo usted mismo en su bomba de mensajes.

En este ejemplo, estamos enviando el temporizador a la bomba de mensajes de hilo, no es necesario tener una ventana asociada al temporizador.

UINT timer; 

VOID CALLBACK Timer(HWND hwnd, 
    UINT uMsg, 
    UINT_PTR idEvent, 
    DWORD dwTime 
) 
{ 
    KillTimer(0, timer); 
} 

timer=SetTimer(0, // window handle 
    0, // id of the timer message, leave 0 in this case 
    10000, // millis 
    Timer // callback 
); 

// pump messages 
while (GetMessage) etc... 

DispatchMessage llamará a la devolución de llamada del temporizador. Esta pregunta me recordó la reciente ONT.

+0

Gracias - Desafortunadamente, no tengo un bucle de mensaje :) – dennisV

+0

¡Así que cree uno! La cola de mensajes está configurada por el sistema operativo una vez que llamas a :: GetMessage o :: PeekMessage. –

5

En lugar de utilizar los temporizadores de IU (aunque puede usar el controlador de ventana NULL como se muestra en el Mr. 1800-INFO) puede usar los objetos del temporizador waitable del kernel. Ver CreateWaitableTimer en los documentos API. Estos pueden ser esperados usando WaitForSingleObject o WaitForMultipleObjects, etc., que es especialmente útil si así es como su servicio espera eventos externos.

Si no está claro desde ese primer enlace, la función SetWaitableTimer puede asociar una rutina de finalización (devolución de llamada del usuario) con el temporizador. Recuerde utilizar las ... versiones Ex de WaitForMultipleObjects (etc.) para que el hilo esté en estado "alertable".

+0

Eso suena bien - Fui con las colas del temporizador, pero también leeré su enlace. ¡Gracias! – dennisV

+0

Gracias, creo que TimerQueues puede ser excesivo, pero realmente depende de cómo se diseñe el resto de su servicio. Si quieres un hilo ThreadPool para manejar el evento del temporizador, TimerQueues sería genial. Si ya tiene un bucle alrededor de WFMO o GetMessage, puede ir con las otras opciones. –

0

¿Estás tratando de "despertar" de vez en cuando para hacer un poco de trabajo? Siempre puedes usar Sleep().

Además, generalmente tengo un hilo que está en un tiempo (1 == 1) lazo con un sueño adentro. Allí puedo verificar la solicitud de cierre y otras tareas domésticas misceláneas. Puede usar ese sistema para hacer un cosquilleo de un evento o mutex para el hilo de trabajo en la aplicación.

+0

No, el servicio está procesando cosas en otros hilos, solo necesito verificar el estado de algunos archivos cada segundo. – dennisV

+0

Probablemente exagerado para usted, pero ... Podría usar ReadDirectoryChangesW para 'escuchar' cambios en los archivos en lugar de sondearlos, probablemente sería más eficiente ya que solo se despertaría cuando hubiera cambios en el proceso en lugar de cada 'x'ms ... Aunque es más difícil de configurar. –

1

En uno de sus comentarios, dijo que "... el servicio está procesando cosas en otros hilos, solo necesito verificar el estado de algunos archivos cada segundo".

El sondeo no es una forma óptima de verificar el estado del archivo, y afectará negativamente el rendimiento del sistema.Si bien hay (a veces) problemas al hacer esto en las redes, debe consultar http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspx o http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx para saber cómo hacerlo y http://blogs.msdn.com/oldnewthing/archive/2006/01/24/516808.aspx para saber por qué debería hacerlo.

+0

Sí, gracias. Sé sobre esas funciones y probablemente tengas razón, debería ser más inteligente y usarlas. Como no tengo control sobre el archivo, solo puedo mirar el tamaño del archivo, pero para ser justos, no lo sondeo continuamente (solo una vez por segundo). – dennisV

Cuestiones relacionadas