2009-06-25 29 views
87

Es gibt drei Timer Klassen, die ich bewusst bin, System.Threading.Timer, System.Timers.Timer und System.Windows.Forms.Timer, aber keiner von ihnen haben eine .Reset() Funktion, die die aktuelle verstrichene Zeit auf 0Wie setze ich einen Timer in C# zurück?

Gibt es eine BCL-Klasse, das hat zurückgesetzt würde Funktionalität? Gibt es einen Non-Hack-Weg, es zu tun? (Ich dachte, vielleicht könnte man das Zeitlimit ändern, um es neu zu setzen.) Dachte man, wie schwer es wäre, eine Timer Klasse, die diese Funktionalität hatte, oder wie man es zuverlässig mit einer der BCL-Klassen macht, neu zu implementieren?

+3

Verwenden Sie JPs Lösung verwenden Sie eine Erweiterungsmethode – benPearce

+0

Ich habe auch die gleiche Notwendigkeit zum Zurücksetzen und aus den gleichen Gründen, FileSystemWatcher ist unangenehm und unbequem zu verwenden –

+0

Wenn Sie Stoppuhr für einen Timer verwenden und mit der Erweiterungsmethode Antwort gehen, sein Vorsicht, da die Stopwatch.Restart-Erweiterungsmethode in .NET 4.0 kommt. http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.restart(VS.100,lightweight).aspx – si618

Antwort

113

ich immer tun ...

myTimer.Stop(); 
myTimer.Start(); 

... ist, dass ein Hack? :)

Per Kommentar, auf Threading.Timer, es ist die Change method ...

dueTime Typ: System.Int32 Die Höhe der Zeit vor dem zu verzögern die Callback-Methode aufruft angegeben, wenn der Timer war konstruiert in Millisekunden. Geben Sie Timeout.Infinite an, um zu verhindern, dass der Timer neu gestartet wird. Geben Sie Null (0) ein, um den Timer sofort neu zu starten.

+0

Das andere Problem ist, dass nur woks mit Forms.Timer, und meine App hat keine GUI (Application.Start() ohne Parameter), so denke ich, dass die Threading.Timer-Klasse aus anderen Gründen besser ist, aber guter Punkt. –

+3

@ Matthew: Siehe http://msdn.microsoft.com/en-us/magazine/cc164015.aspx für eine Diskussion der verschiedenen Timer-Klassen und wenn sie verwendet werden, ist angemessen. Im Allgemeinen sollte 'Forms.Timer' jedoch nur mit einer GUI verwendet werden. Neben 'Forms.Timer' und' Threading.Timer' gibt es aber auch 'Timers.Timer'. – Brian

44

Alle Timer entsprechen den Methoden Start() und Stop(), außer System.Threading.Timer.

So eine Erweiterungsmethode wie ...

public static void Reset(this Timer timer) 
{ 
    timer.Stop(); 
    timer.Start(); 
} 

... ist eine Möglichkeit, darüber zu gehen.

+1

Ich möchte die verstrichene Zeit nicht messen. Mein genauer Anwendungsfall dafür ist, dass ich einen FileSystemWatcher habe, der ein Verzeichnis beobachtet und Gruppen von Änderungen abfangen will (dh Änderungen, die innerhalb von beispielsweise 5s voneinander gemacht werden). Die Theorie besagt, dass die erste Änderung einen Timer startet, der bei jeder Änderung zurückgesetzt wird, bis die Gruppe schließlich ausgelöst und geschlossen wird. –

+0

Ja, das habe ich gesehen, als ich deine Frage noch einmal gelesen habe. Bearbeitete meine Antwort. – Dan

4

Sie könnten eine Erweiterungsmethode namens Reset() schreiben, die

  • ruft Stop() - Start() für Timers.Timer und Forms.Timer
  • Anrufe ändern für Threading.Timer
1

Andere alternative Möglichkeit, den windows.timer zurückgesetzt wird den Zähler verwendet wird, wie folgt:

int tmrCtr = 0; 
Timer mTimer; 

private void ResetTimer() 
{ 
    tmrCtr = 0; 
} 

private void mTimer_Tick() 
{ 
    tmrCtr++; 
    //perform task 
} 

Wenn Sie also alle 1 Sekunde wiederholen möchten, können Sie das Timerintervall auf 100 ms einstellen und den Zähler auf 10 Zyklen testen.

Dies ist geeignet, wenn der Timer auf einige Prozesse warten soll, die zu unterschiedlichen Zeitpunkten beendet werden können.

2

Für einen Timer (System.Windows.Forms.Timer).

Die .Stop, dann .Start-Methoden funktionierten als Reset.

19

Für System.Timers.Timer nach MSDN-Dokumentation, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx:

Wenn das Intervall eingestellt wird, nachdem der Timer gestartet wird, ist die Anzahl zurückgesetzt.Wenn Sie beispielsweise das Intervall auf 5 Sekunden festlegen und dann die Eigenschaft Enabled auf setzen, beginnt die Zählung zu dem Zeitpunkt, zu dem Enabled festgelegt ist. Wenn Sie das Intervall bei 10 Sekunden auf 10 Sekunden zurücksetzen, wird das Ereignis Elapsed zum ersten Mal 13 Sekunden nach Enabled auf true gesetzt.

So

const double TIMEOUT = 5000; // milliseconds 

    aTimer = new System.Timers.Timer(TIMEOUT); 
    aTimer.Start();  // timer start running 

    : 
    : 

    aTimer.Interval = TIMEOUT; // restart the timer 
+1

Problem hier ist, dass Sie nicht immer in dem Moment wissen, dass Sie zurücksetzen möchten, wenn der Timer bereits läuft oder nicht. Also müssten Sie aTimer.Interval = TIMEOUT und atimer.Start() ausführen. Insgesamt verwendet eine obige Reset-Funktion weniger Zeilen und Variablen. Toller Zusatz. –

+1

@ R-U-Bn Das OP gibt eindeutig "* a .Reset()" -Funktion an, die die aktuelle verstrichene Zeit auf 0 * zurücksetzen würde."- es erwähnt nicht, dass es auf einer schlecht entworfenen Anwendung verwendet werden soll, wo Sie nicht einmal wissen, ob der Timer läuft. Überprüfen Sie auch den Autor Kommentar (vor mehr als 4 Jahren):" * Die Theorie ist, dass Die erste Änderung startet einen Timer, der mit jeder Änderung zurückgesetzt wird, bis er schließlich ausgelöst wird und die Gruppe schließt. * "Danke für die Abstimmungen. – mMontu

+0

Egal, es ist nur eine zusätzliche Information für andere Leute. PS Ich habe nicht 't nur unten, ich nahm nur meine Upvote zurück. PPS Nicht so leicht auf dein Pferd. –

3

ich einen neuen Wert in den Timer nur zugewiesen:

mytimer.Change(10000, 0); // reset to 10 seconds 

es funktioniert gut für mich.

an der Spitze des Codes definieren den Timer: System.Threading.Timer myTimer;

if (!active) 
     { 
      myTimer= new System.Threading.Timer(new TimerCallback(TimerProc)); 
     } 
     myTimer.Change(10000, 0); 
     active = true; 

private void TimerProc(object state) 
    { 
     // The state object is the Timer object. 
     System.Threading.Timer t = (System.Threading.Timer)state; 
     t.Dispose(); 
     Console.WriteLine("The timer callback executes."); 
     active = false; 
     //action to do when timer is back to zero 
    } 
0

ich dieses

//Restart the timer 
queueTimer.Enabled = true; 
+0

Dies aktiviert nur. Auch wenn es zuvor deaktiviert wurde, ändert die erneute Aktivierung nicht die verstrichene Zeit, die gesammelt worden war bis zu diesem Punkt. – vapcguy

0

Sie timer.Interval = timer.Interval tun können

0

Aus Gründen der Klarheit, da einige andere Kommentare falsch sind, wenn unter Verwendung von System.Timers Einstellung aktiviert zu True wird zurückgesetzt die verstrichene Zeit. Getestet habe ich nur das Verhalten mit der unten:

Timer countDown= new Timer(); 

Main() 
{ 
    TextBox.TextDidChange += TextBox_TextDidChange; 
    countdown.Elapsed += CountDown_Elapsed; 
} 

void TextBox_TextDidChange(Object sender, EventArgs e) 
{ 
    countdown.Enabled = true; 
} 

void CountDown_Elapsed(object sender, EventArgs e) 
{ 
    System.Console.WriteLine("Elapsed"); 
} 

Ich würde Eingabe von Text in das Textfeld wiederholt und der Timer würde nur 3 Sekunden nach dem letzten Tastendruck ausgeführt werden. Es wird auch in den Dokumenten angedeutet, wie Sie sehen werden, wenn Sie "Timers.Start()" aufrufen, wird Enabled einfach auf "true" gesetzt.

Und um sicher zu sein, zu dem ich von Anfang an einfach hätte gehen sollen, sehen Sie in der .NET reference source, dass wenn die Aktivierung eines bereits aktivierten Timers die private UpdateTimer() Methode aufruft, die intern Change ().

Verwandte Themen