2011-05-25 10 views
7

Jak zmienić interwał w System.Threading.Timer z funkcji wywołania zwrotnego tego timera? Czy to prawda?Jak zmienić interwał czasowy w System.Threading.Timer z funkcji wywołania zwrotnego tego timera?

Takie postępowanie. Nie wydarzyło się.

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

jeśli (prawda) ??? ......... –

+1

@Mitch Wheat, to jest ważne z jakiegoś dobrego powodu, testowanie na przykład? – crypted

+1

Mitch, to tylko przykład. Nie bierz tego do serca. lol – mrbrooks

Odpowiedz

8

Linia ta generować nieskończoną rekurencję:

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

Pierwsze siły parametrów TimerCallBack do wykonania od razu. Tak więc wykonuje to raz po raz przez czas nieokreślony.

Rozwiązaniem byłoby

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

Dziękuję bardzo! – mrbrooks

4

Problemem jest to, że wezwanie do Change określa, że ​​obok wezwanie powinno się zdarzyć natychmiast. Jeśli zamierzasz zadzwonić pod numer Changeco godzinę, możesz po prostu użyć okresu Timeout.Infinite (który jest tylko stałą wartości -1), aby powiedzieć, aby w ogóle nie powtórzył się po następnym czasie - ale nadal będzie kontynuował ostrzał , ponieważ następnym razem zresetujesz go. Na przykład:

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)); 
    } 
} 

Alternatywnie, można ją zmienić tylko raz, a następnie pozostawić go:

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); 
     } 
    } 
} 

Zauważ, że nic nie jest za pomocą początkowego przedziału (1 sekunda w próbkach powyżej), w obu przypadkach , ponieważ natychmiast dzwonimy pod numer Change - jeśli naprawdę chcesz mieć inny czas przed pierwszym połączeniem, nie używaj TimeSpan.Zero w pierwszym połączeniu z numerem Change.

+0

Dziękuję bardzo! – mrbrooks

+0

Tylko dla zapisu, podczas gdy możesz oczywiście użyć -1 dla "Infinite", doktorzy mówią, że możesz użyć 'Timeout.Infinite', który, jak sądzę, wyraźniej pokazuje intencję. ;) –

+0

@JamesWilkins: True Will edit. (Chociaż jeśli 'Timeout.Infinite' byłby' TimeSpan', to byłoby bardziej zrozumiałe - dokumenty dla 'Timer.Change (int, int)' wspominają 'Timeout.Infinite', dokumenty dla' Timer.Change (TimeSpan, TimeSpaan) 'do not :( –

Powiązane problemy