2009-06-25 10 views
87

Il y a trois Timer cours que je suis au courant, System.Threading.Timer, System.Timers.Timer et System.Windows.Forms.Timer, mais aucun d'entre eux ont une fonction .Reset() qui réinitialiser le temps écoulé actuel à 0.Comment réinitialiser une minuterie en C#?

Y at-il une classe BCL qui a cette fonctionnalité? Y a-t-il une façon non-hack de le faire? (Je pensais que peut-être changer la limite de temps sur elle pourrait le réinitialiser) Pensé sur combien il serait difficile de réimplémenter une classe Timer qui avait cette fonctionnalité, ou comment le faire de manière fiable avec l'une des classes BCL?

+3

En utilisant la solution de JP utiliser une méthode d'extension – benPearce

+0

J'ai aussi le même besoin de réinitialisation et pour les mêmes raisons mentionnées, FileSystemWatcher est désagréable et incommode à utiliser –

+0

Si vous utilisez Chronomètre pour une minuterie et aller avec la méthode d'extension réponse, soyez attention parce que la méthode d'extension Stopwatch.Restart arrive dans .NET 4.0. http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.restart(VS.100,lightweight).aspx – si618

Répondre

113

Je fais toujours ...

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

... est-ce un hack? :)

par commentaire, sur Threading.Timer, il est le Change method ...

dueTime Type: System.Int32 La quantité de temps à attendre avant la appeler la méthode de rappel spécifiée lorsque la minuterie était construit, en millisecondes. Indiquez Timeout.Infinite pour empêcher le redémarrage du temporisateur . Spécifiez zéro (0) pour redémarrer la minuterie immédiatement.

+0

L'autre problème est que seulement Woeks avec Forms.Timer, et mon application n'a pas GUI (Application.Start() sans paramètres), donc je pense que la classe Threading.Timer est mieux pour d'autres raisons, mais bon point. –

+3

@Matthew: Voir http://msdn.microsoft.com/en-us/magazine/cc164015.aspx pour une discussion sur les différentes classes de temporisation et en les utilisant est approprié. En général, cependant, 'Forms.Timer' ne devrait être utilisé qu'avec une interface graphique. Cependant, outre 'Forms.Timer' et' Threading.Timer', il y a aussi 'Timers.Timer'. – Brian

44

Tous les temporisateurs ont l'équivalent des méthodes Start() et Stop(), à l'exception de System.Threading.Timer.

Ainsi, une méthode d'extension telle que ...

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

... est une façon d'aller à ce sujet.

+1

Je ne cherche pas à mesurer le temps écoulé. Mon utilisation exacte pour ceci est que j'ai un FileSystemWatcher regardant un répertoire et que je veux attraper des groupes de changements (c.-à-d., Des changements faits par exemple à 5s l'un de l'autre). La théorie étant que le premier changement commence une minuterie qui se réinitialise à chaque changement jusqu'à ce qu'il finisse par se déclencher et ferme le groupe. –

+0

Oui, j'ai repéré ça quand j'ai relu ta question. Edited ma réponse. – Dan

4

Vous pouvez écrire une méthode d'extension appelée Reset(), qui

  • appelle Stop() - Démarrer() pour Timers.Timer et Forms.Timer
  • appels Modifier pour Threading.Timer
1

Autre alternative pour réinitialiser le windows.timer est en utilisant le compteur, comme suit:

int tmrCtr = 0; 
Timer mTimer; 

private void ResetTimer() 
{ 
    tmrCtr = 0; 
} 

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

Donc, si vous avez l'intention de répéter toutes les secondes, vous pouvez régler l'intervalle de la minuterie à 100 ms et tester le compteur à 10 cycles.

Ceci est approprié si le temporisateur doit attendre certains processus qui peuvent être terminés à différentes périodes.

2

Pour un minuteur (System.Windows.Forms.Timer).

Les méthodes .Stop, puis .Start ont fonctionné comme une réinitialisation.

19

Pour System.Timers.Timer, selon la documentation MSDN, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx:

Si l'intervalle est réglé après la minuterie a démarré, le compte est remis à zéro .Par exemple, si vous définissez l'intervalle sur 5 secondes et que vous définissez la propriété Enabled sur true, le compte commence à l'instant Activé est défini. Si vous réinitialisez l'intervalle à 10 secondes lorsque le compte est de 3 secondes, l'événement Elapsed est déclenché pour la première fois 13 secondes après que Enabled a été défini sur true.

Ainsi,

const double TIMEOUT = 5000; // milliseconds 

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

    : 
    : 

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

Problème ici est que vous ne savez pas toujours au moment où vous souhaitez réinitialiser si la minuterie est déjà en cours d'exécution ou non. Donc, vous devriez faire aTimer.Interval = TIMEOUT et un aTimer.Start(). Donc, dans l'ensemble, une fonction de réinitialisation ci-dessus utilise moins de lignes et de variables. Grande addition cependant. –

+1

@ R-U-Bn L'OP indique clairement "* une fonction .Reset() qui réinitialiserait le temps écoulé actuel à 0 *."- il ne mentionne pas qu'il est destiné à être utilisé sur une application de mauvaise conception où vous ne savez même pas si la minuterie est en cours.Vérifiez également le commentaire de l'auteur (il y a plus de 4 ans):" * La théorie étant que le premier changement commence une minuterie qui se réinitialise à chaque changement jusqu'à ce qu'il finisse par se déclencher et ferme le groupe. *. "Merci pour le vote vers le bas, de toute façon – mMontu

+0

Peu importe, c'est juste des infos supplémentaires pour d'autres personnes. –

3

Je viens d'une nouvelle valeur affecté à la minuterie:

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

cela fonctionne très bien pour moi.

en haut du code définissent la minuterie: 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

-je faire

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

Cela ne fait qu'accrocher votre cheval, même s'il a été désactivé au préalable, la réactivation ne modifie pas le temps écoulé. à ce point. – vapcguy

0

Vous pouvez faire timer.Interval = timer.Interval

0

Pour plus de clarté puisque d'autres commentaires sont incorrects, lorsque en utilisant le paramètre System.Timers Activé sur réinitialisera le temps écoulé. Je viens de tester le comportement avec le ci-dessous:

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

Je voudrais saisir du texte à la zone de texte à plusieurs reprises et la minuterie ne ferait courir 3 secondes après la dernière pression de touche. Cela est également indiqué dans les documents, comme vous le verrez lorsque vous appelez 'Timers.Start()' définit simplement Enabled sur true.

Et pour être sûr, que j'aurais dû aller directement au début, vous verrez dans le .NET reference source qu'en activant une minuterie déjà activée, elle appelle la méthode privée UpdateTimer(), qui appelle en interne Change ().

Questions connexes