2011-01-13 6 views
6

tengo dos alternativas mediante temporizador o el uso de sueño, tengo que llamar a un método cada 3 segundos después de que se terminó este método, escribí ejemplo básico para demostrar lo que quiero decir:¿Qué debo usar el sueño o el temporizador de

public static void Main() 
{ 
    new Thread(new ThreadStart(fooUsingSleep)).Start(); 

    callToMethodAfterInterval(new Action<object, ElapsedEventArgs>(fooUsingTimer), 3000); 
} 

public static void fooUsingSleep() 
{ 
    Console.WriteLine("Doing some consuming time work using sleep"); 
    Thread.Sleep(3000); 
    fooUsingSleep(); 
} 

public static void fooUsingTimer(object dummy, ElapsedEventArgs dummyElapsed) 
{ 
    Console.WriteLine("Doing some consuming time work usning timer"); 
    callToMethodAfterInterval(new Action<object, ElapsedEventArgs>(fooUsingTimer), 3000); 
} 

public static void callToMethodAfterInterval(Action<object,ElapsedEventArgs> inMethod, int inInterval) 
{ 
    System.Timers.Timer myTimer = new System.Timers.Timer(); 
    myTimer.Elapsed += new ElapsedEventHandler(inMethod); 
    myTimer.Interval = inInterval; 
    myTimer.AutoReset = false; 
    myTimer.Start(); 
} 

Entonces mis preguntas son

1) ¿Puedo escribir el código con el temporizador más elegante? Significa eliminar la llamada al método callToMethodAfterInterval de fooUsingTimer, hacer que el temporizador sea de una o dos líneas, y eliminar las variables ficticias de la declaración de fooUsingTimer?

2) Entiendo que el sueño no está ocupado esperando (http://www.codeproject.com/KB/threads/ThreadingDotNet.aspx) Así que no encontré la justificación para usar la opción de temporizador aquí, porque el el sueño es más simple, ¿qué es mejor usar, la versión del temporizador o la del sueño?

3) Sé que Timers.timer es seguro para subprocesos, ¿me puede ayudar en el comportamiento que deseo implementar?

Gracias.

Respuesta

2

También importa el contexto real de su programa.

La opción de suspensión 'desperdicia' un subproceso, no es un problema en una aplicación de consola pequeña, pero en general no es una buena idea.

No es necesario reiniciar el temporizador, el siguiente mantendrá tictac:

static void Main(string[] args) 
    { 
     var t = new System.Timers.Timer(1000); 
     t.Elapsed += (s, e) => CallMeBack(); 
     t.Start(); 

     Console.ReadLine(); 
    } 
+1

Me gustaría señalar que no creo que esto sea exactamente lo que se suponía que estaba haciendo el original, era hacer una tarea larga y luego volver a ejecutarla 3 segundos después de que se completara. ¿La suya se ejecutará cada segundo? – Paddy

+0

@Paddy, correcto, estaba asumiendo una tarea relativamente corta. El OP debería decir. –

+0

No quiero que se llame a la opción foo antes de que las otras llamadas a foo hayan terminado ... – Delashmate

0

El sueño hará el truco, Timer por otro lado ha sido diseñado para ese propósito exacto, las convenciones son mejores y generalmente harán que su código sea más comprensible.

+0

¿Cómo puedo escribir la parte más elegante temporizador? – Delashmate

3

¿Se da cuenta de que fooUsingSleep está llamando una y otra vez? Eventualmente generará un desbordamiento de pila.

Si está utilizando el temporizador, que puede ser tan simple como esto:

System.Windows.Forms.Timer t = new System.Windows.Forms.Timer(); 
    t.Interval = 3000; 
    t.Tick += new EventHandler((o,ea) => Console.WriteLine("foo")); 
+0

+1 para una solución elegante, ¿cómo causará el desbordamiento de la pila? No puedo verlo, en su solución se puede llamar al método antes de que el último haya terminado y puede llevar a errores difíciles de encontrar, por lo que esta razón no marqué como respuesta – Delashmate

+1

no se puede llamar antes de la última ha terminado porque se ejecutan en el mismo hilo. Tu solución (al llamar a fooUsingSleep() desde dentro de fooUsingSleep() eventualmente se desbordará la pila porque en cada método se inserta el contexto de ejecución en una pila, que no tiene capacidad ilimitada) – Axarydax

+0

Ok, ahora entiendo el desbordamiento de la pila que mencionas:) – Delashmate