2010-08-13 16 views
7

Tengo un servicio que acierta en una base de datos cada 10 segundos y obtiene los datos si los hay. Lo que pasa es que procesar estos datos puede llevar hasta 30 segundos. Si uso un temporizador con un intervalo de 10 segundos, el servicio obtendrá los mismos datos dos veces.C# Timer vs Thread en el servicio

El efecto Estoy tratando de lograr (Sólo para visualización):

while(true) 
{ 
    if(Getnrofrows() > 0) 
     do stuff 
    else 
     sleep for 10 sec 
} 

pers diciendo Thread.Sleep es una mala idea en servicios de producción, ¿cómo puedo hacer esto con temporizadores?

/mike

+4

¿También están diciendo * why * Thread.Sleep es una mala idea? – Heinzi

Respuesta

10

¿trató de programar el temporizador de la propiedad de reposición automática a falso, y permitiendo de nuevo el temporizador cuando el proceso de refresco de datos ha terminado

using System; 

public class PortChat 
{ 
    public static System.Timers.Timer _timer; 
    public static void Main() 
    { 

     _timer = new System.Timers.Timer(); 
     _timer.AutoReset = false; 
     _timer.Interval = 100; 
     _timer.Elapsed += new System.Timers.ElapsedEventHandler(_timer_Elapsed); 
     _timer.Enabled = true; 
     Console.ReadKey(); 
    } 

    static void _timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     //Do database refresh 
     _timer.Enabled = true; 
    } 
} 
+0

Exactamente lo que estaba buscando. ¡Gracias! –

+0

Lo sentimos, pero ¿no debería ser _timer.Enabled = false en el evento transcurrido? ¿Por qué se establece en true nuevamente si se hace en main? – Neale

+0

@Neale, la pregunta original era sobre pausar el ciclo hasta que algo no haya terminado. Cuando ponemos _timer.Autoreset = false, el ciclo solo ocurrirá una vez después de habilitar el temporizador. Entonces, cuando nuestro bucle termine con la lectura, activaremos nuevamente el temporizador habilitándolo – adopilot

0

No hay nada malo con este enfoque. Un hilo que duerme no consume ningún ciclo de CPU.

Si necesita hacer algo exactamente cada X segundos, un temporizador es el camino a seguir. Si, por el contrario, desea pausar durante X segundos, entonces Thread.Sleep es apropiado.

+0

Un hilo que duerme no puede consumir ningún ciclo de CPU, pero consumirá muchos recursos del núcleo en comparación con el objeto del temporizador. – Zuuum

1

No veo ningún problema con el uso de Sleep en absoluto de lo que podría terminar con el código feo.

Para responder a su pregunta:

public class MyTest 
{ 
    System.Threading.Timer _timer; 


    public MyTest() 
    { 
     _timer = new Timer(WorkMethod, 15000, 15000); 
    } 


    public void WorkMethod() 
    { 
     _timer.Change(Timeout.Infinite, Timeout.Infinite); // suspend timer 

     // do work 

     _timer.Change(15000, 15000); //resume 

    } 
} 
0

Thread.Sleep no es malo en sí mismo en un servicio, sólo que tiene que ser sensible a los comandos de servicio, por lo que su subproceso de trabajo no debe ir a dormir durante una hora, sino que necesita dormir por períodos cortos de tiempo y luego se despierta y escucha si la parte del servicio del controlador le dice que se detenga por alguna razón.

Quiere que el administrador le indique a su servicio que pare, lo hará con la suficiente rapidez para que no reciba ningún mensaje de tiempo de espera en el que el administrador no pueda estar seguro de que su servicio está detenido y es seguro reiniciar la máquina o similar.