2011-05-25 9 views
7

¿Cómo cambio el intervalo en System.Threading.Timer desde la función de devolución de llamada de este temporizador? ¿Es esto correcto?¿Cómo cambio el tiempo de intervalo en System.Threading.Timer desde la función de devolución de llamada de este temporizador?

Si lo hace. No pasó.

public class TestTimer 
{ 
    private static Timer _timer = new Timer(TimerCallBack); 

    public void Run() 
    { 
     _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(1)); 
    } 

    private static void TimerCallBack(object obj) 
    { 
     if(true) 
      _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(10)); 
    } 

} 
+2

si (true) ??? ......... –

+1

@Mitch Wheat, ¿eso es válido por alguna buena razón, prueba por ejemplo? – crypted

+1

Mitch, es solo un ejemplo. No te lo tomes a pecho. lol – mrbrooks

Respuesta

8

Esta línea de generar una recursión infinita:

if(true) 
    _timer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(10)); 

Las primeras fuerzas de parámetros TimerCallBack para ejecutar de inmediato. Entonces lo ejecuta una y otra vez indefinidamente.

La solución sería

if(true) 
    _timer.Change(TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); 
+0

¡Muchas gracias! – mrbrooks

4

El problema es que su llamada a Change especifica que el siguiente llamada debe suceder inmediatamente . Si va a llamar al Changecada vez, puede simplemente usar un período de Timeout.Infinite (que es solo una constante de -1) para indicarle que evite repetirlo después de la próxima vez, pero seguirá disparando porque la próxima vez lo restableces Por ejemplo:

using System; 
using System.Threading; 

static class Program 
{ 
    private static Timer timer = new Timer(TimerCallBack); 

    public static void Main() 
    { 
     timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1)); 
     Thread.Sleep(10000); 

    } 

    private static void TimerCallBack(object obj) 
    { 
     Console.WriteLine("{0}: Fired", DateTime.Now); 
     timer.Change(TimeSpan.FromSeconds(3), 
        TimeSpan.FromMilliseconds(Timeout.Infinite)); 
    } 
} 

Como alternativa, puede cambiar sólo una vez, y luego dejarlo:

using System; 
using System.Threading; 

static class Program 
{ 
    private static Timer timer = new Timer(TimerCallBack); 
    private static bool changed = false; 

    public static void Main() 
    { 
     timer.Change(TimeSpan.Zero, TimeSpan.FromSeconds(1)); 
     Thread.Sleep(10000); 

    } 

    private static void TimerCallBack(object obj) 
    { 
     Console.WriteLine("{0}: Fired", DateTime.Now); 
     if (!changed) 
     { 
      changed = true; 
      TimeSpan interval = TimeSpan.FromSeconds(3); 
      timer.Change(interval, interval); 
     } 
    } 
} 

Tenga en cuenta que nada está utilizando el intervalo inicial (1 segundo en los ejemplos anteriores), en ambos casos , porque estamos llamando Change inmediato - si realmente quieres un tiempo diferente antes de la primera llamada, no utilice TimeSpan.Zero en la llamada inicial a Change.

+0

¡Muchas gracias! – mrbrooks

+0

Sólo para que conste, mientras que por supuesto puede utilizar -1 para "Infinito", los documentos no decir que usted puede usar 'Timeout.Infinite', que creo que muestra más claramente la intención. ;) –

+0

@JamesWilkins: True Will edit. (Aunque si 'Timeout.Infinite' fuera un' TimeSpan' sería más claro - la documentación para 'Timer.Change (int, int)' 'mencionar Timeout.Infinite'; la documentación para' Timer.Change (TimeSpan, TimeSpaan) 'no :( –

Cuestiones relacionadas