2012-01-10 31 views
8

Estoy trabajando en una aplicación de consola que se programará y ejecutará a intervalos establecidos, por ejemplo, cada 30 minutos. Su único propósito es consultar un servicio web para actualizar un lote de filas de bases de datos.Uso aceptable de Thread.Sleep()

La API del servicio web recomienda llamar una vez cada 30 segundos y el tiempo de espera después de un intervalo establecido. El siguiente pseudocódigo se da como un ejemplo:

listId := updateList(<list of terms>) 
LOOP 
    WHILE NOT isUpdatingComplete(listId) 
END LOOP 
statuses := getStatuses(“LIST_ID = {listId}”) 

me han codificado esta aproximadamente en C# como:

int callCount = 0; 
while(callCount < 5 && !client.isUpdateComplete(listId, out messages)) 
{ 
    listId = client.updateList(options, terms, out messages); 
    callCount++; 
    Thread.Sleep(30000); 
} 
// Get resulting status... 

¿Está bien en esta situación para utilizar Thread.Sleep()? Soy consciente de que, en general, no es una buena práctica, pero al leer las razones para no usarlo, parece un uso aceptable.

Gracias.

+1

Tu uso de 'Thread.Sleep' es perfectamente aceptable –

+4

La aplicación de la consola se programará ? ¿Por qué no programarlo solo cada 30 minutos si ese es el caso? La mejor solución sería un servicio de Windows que utiliza un temporizador para llamar al método. – Ray

+0

¿Por qué no? ¿Cuáles son las razones para no usarlo? –

Respuesta

6

Thread.Sleep asegura el subproceso actual no se devuelve hasta al menos los milisegundos especificados han pasado. Hay muchos lugares apropiados para hacerlo, y su ejemplo parece correcto, suponiendo que se ejecute en un hilo de fondo.

Algunos ejemplos de lugares donde no desea utilizarlos: en el hilo de la interfaz de usuario o donde debe realizar el tiempo exacto.

+3

Creo que su calificación "suponiendo que se ejecuta en un hilo de fondo" está bien, pero en este caso la aplicación parece ser una aplicación de consola que se ejecutará automáticamente como una tarea programada, por lo que creo que en este caso no es necesario asegúrese de que se ejecuta en un hilo de fondo. Si esta fuera una aplicación interactiva, estaría completamente de acuerdo con su calificación. –

+0

Me refiero a la cadena de fondo por cualquier hilo que se ejecute en el fondo, es decir, no un subproceso de interfaz de usuario. Subprocesos de servicio Consideraría los hilos de fondo. (No me refiero a 'IsBackground' en los objetos de subprocesos, que simplemente se refiere a cómo se destruyen/limpian los subprocesos al salir de la aplicación, IIRC). Vaya, no te vi decir la consola. Sí, esa es una terminología discutible, pero en realidad no es un hilo de fondo, de acuerdo. Entonces podría argumentar que una aplicación de consola no es tan apropiada. –

+1

Ah, entiendo lo que quieres decir. :) No tenía la intención de discutir la semántica, pero su comentario me hizo darme cuenta de que en este caso, el "hilo principal" de la aplicación de la consola podría considerarse como un hilo de "fondo" porque no hay interacción del usuario. –

3

La objeción general contra el Sueño() es que desperdicia un hilo.

En su caso, solo hay 1 hilo (quizás 2), así que eso no es realmente un problema.

Así que creo que se ve bien (pero me gustaría dormir 29 segundos para reducir la holgura).

+0

No estoy convencido de lo de 29 segundos .. Amazon requiere 60 segundos entre algunas llamadas API. 'Thread.Sleep (60 * 1000)' aún genera un error al hablar de un retraso de 60 segundos en casos excepcionales, por lo que en * ese * caso específico duermo durante 62 segundos, es decir, le otorgo * más * holgura. YMMV y todo eso ... –

1

Está bien, excepto que no puede interrumpirlo una vez que está en reposo, sin abortar el hilo (que no se recomienda).

Es por eso que ManualResetEvent podría ser una mejor idea, ya que se puede señalar ("despertar") desde un hilo diferente.

1

puede seguir el método Thread.Sleep. Pero sería más elegante programar su ejecución cada 30 minutos, para que no tenga que ocuparse de la espera dentro de su aplicación.

5

En términos generales, Thread.Sleep es como cualquier otra herramienta: perfectamente bien para su uso, excepto cuando se usa de forma incorrecta. No estoy de acuerdo con la parte "generalmente no es buena práctica", que es el resultado de personas que abusan de Thread.Sleep cuando deberían estar haciendo otra cosa (es decir, bloquear en un objeto de sincronización).

En su caso, el programa es de subproceso único, no tiene UI (es decir, el subproceso no tiene ningún bucle de mensaje) y no desea sincronizar con eventos externos. Por lo tanto, Thread.Sleep está bien.

0

Thread.Sleep no es el mejor para ejecutar lógica periódica. Thread.Sleep (n) significa que su hilo renunciará al control durante n milisegundos. No hay garantía de que recuperará el control después de n milisegundos, depende de la carga de la CPU.

0

Si está bloqueando el hilo durante 30 minutos, debe programar una tarea de Windows cada 30 minutos, para que el programa se ejecute y luego finalice. De esa forma no estás bloqueando un hilo por tanto tiempo.

Para tiempos más cortos, como 30 segundos/1 min, System.Thread.Sleep() está perfectamente bien. Durante más de 5 minutos usaría una tarea de Windows. (Soy español, creo que en la versión en inglés se llaman así, estoy hablando de las tareas que programes desde el panel de control ;-))