Come resettare un timer in C #?


114

Ci sono tre Timerclassi che sono a conoscenza di, System.Threading.Timer, System.Timers.Timer, e System.Windows.Forms.Timer, ma nessuno di questi hanno una .Reset()funzione che potrebbe azzerare il tempo trascorso corrente a 0.

Esiste una classe BCL che dispone di questa funzionalità? Esiste un modo non hacker per farlo? (Ho pensato che forse la modifica del limite di tempo potrebbe resettarlo) Hai pensato a quanto sarebbe stato difficile reimplementare una Timerclasse che avesse questa funzionalità o come farlo in modo affidabile con una delle classi BCL?


3
Utilizzando la soluzione di JP utilizzare un metodo di estensione
benPearce

Anch'io ho la stessa necessità di ripristino e per gli stessi motivi menzionati, FileSystemWatcher è sgradevole e scomodo da usare
John Lewin

Se usi Stopwatch per un timer e scegli il metodo di estensione answer, fai attenzione perché il metodo di estensione Stopwatch.Restart è disponibile in .NET 4.0. msdn.microsoft.com/en-us/library/...
si618

Risposte:


148

Lo faccio sempre ...

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

... è un trucco? :)

Per commento, su Threading.Timer, è il metodo Change ...

dueTime Type: System.Int32la quantità di tempo da ritardare prima del richiamo del metodo di callback specificato quando è stato costruito il Timer, in millisecondi. Specificare Timeout.Infiniteper impedire il riavvio del timer. Specificare zero (0) per riavviare immediatamente il timer.


L'altro problema è che funziona solo con Forms.Timer e la mia app non ha GUI (Application.Start () senza parametri), quindi PENSO che la classe Threading.Timer sia migliore per altri motivi, ma buon punto.
Matthew Scharley,

3
@ Matthew: vedere msdn.microsoft.com/en-us/magazine/cc164015.aspx per una discussione sulle varie classi di timer e quando è appropriato utilizzarle. In generale, tuttavia, Forms.Timerdovrebbe essere utilizzato solo con una GUI. Tuttavia, inoltre Forms.Timere Threading.Timerc'è anche Timers.Timer.
Brian

60

Tutti i timer hanno l'equivalente dei metodi Start () e Stop (), tranne System.Threading.Timer.

Quindi un metodo di estensione come ...

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

... è un modo per farlo.


1
Non sto cercando di misurare il tempo trascorso. Il mio esatto caso d'uso per questo è che ho un FileSystemWatcher che controlla una directory e voglio catturare gruppi di modifiche (cioè, modifiche apportate ad esempio all'interno di 5 secondi l'una dall'altra). La teoria è che la prima modifica avvia un timer che viene ripristinato con ogni modifica fino a quando non si attiva e chiude il gruppo.
Matthew Scharley,

Sì, l'ho notato quando ho riletto la tua domanda. Ho modificato la mia risposta.
Dan

Funziona ed è importante notare che non funzionerà se chiami solo timer.Start(). Ho fatto questa query su Linqpad per testarla. Prova a rimuoverlo timer.Stope vedrai la differenza.
Jared Beach

30

Per System.Timers.Timer, secondo la documentazione MSDN, http://msdn.microsoft.com/en-us/library/system.timers.timer.enabled.aspx :

Se l'intervallo viene impostato dopo l'avvio del timer, il conteggio viene azzerato. Ad esempio, se si imposta l'intervallo su 5 secondi e quindi si imposta la proprietà Enabled su true, il conteggio inizia nel momento in cui viene impostato Enabled. Se si reimposta l'intervallo a 10 secondi quando il conteggio è di 3 secondi, l'evento Elapsed viene generato per la prima volta 13 secondi dopo che Enabled è stato impostato su true.

Così,

    const double TIMEOUT = 5000; // milliseconds

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

    :
    :

    aTimer.Interval = TIMEOUT;  // restart the timer

1
Il problema qui è che non sempre sai al momento di voler ripristinare se il timer è già in esecuzione o meno. Quindi, dovresti fare aTimer.Interval = TIMEOUT e aTimer.Start (). Quindi, nel complesso, una funzione di ripristino sopra utilizza meno righe e variabili. Ottima aggiunta però.
e-motiv

1
@ RU-Bn L'OP indica chiaramente " una funzione .Reset () che reimposta il tempo trascorso corrente a 0 ". - non menziona che è destinato all'uso su un'applicazione progettata in modo scadente in cui non sai nemmeno se il timer è in esecuzione. Controlla anche il commento dell'autore (più di 4 anni fa): " La teoria è che la prima modifica avvia un timer che viene azzerato ad ogni modifica fino a quando non si attiva e chiude il gruppo ". Grazie per il voto negativo, comunque.
mMontu

Ho visto anche un problema del genere. Quello che ho fatto è: aTimer.Interval = aTimer.Interval. Ciò ha innescato che il ciclo stava andando avanti. Mi batte perché ma funziona ...
Herman Van Der Blom

7

Potresti scrivere un metodo di estensione chiamato Reset (), che

  • chiama Stop () - Start () per Timers.Timer e Forms.Timer
  • chiama Change per Threading.Timer

5

Ho appena assegnato un nuovo valore al timer:

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

per me funziona bene.

nella parte superiore del codice definire il 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
    }

5

Per chiarezza poiché alcuni altri commenti non sono corretti, quando si utilizza l' System.Timersimpostazione Enabled su true si azzera il tempo trascorso. Ho appena testato il comportamento con quanto segue:

Timer countDown= new Timer(3000);

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

Vorrei inserire ripetutamente il testo nella casella di testo e il timer verrà eseguito solo 3 secondi dopo l'ultima pressione di un tasto. È anche accennato nei documenti, come vedrai: la chiamata Timers.Start()imposta semplicemente Enabled su true.

E per essere sicuro, a cui avrei dovuto andare direttamente dall'inizio, vedrai nella sorgente di riferimento .NET che se abilita un timer già abilitato chiama il UpdateTimer()metodo privato , che chiama internamente Change().


No ti sbagli. Il UpdateTtimermetodo privato viene chiamato se e solo se il valore corrente di Enablednon è uguale al nuovo value.
Nicolò Carandini

3

Per un timer (System.Windows.Forms.Timer).

I metodi .Stop, quindi .Start hanno funzionato come un ripristino.


1

Un altro modo alternativo per resettare windows.timer è usare il contatore, come segue:

int tmrCtr = 0;
Timer mTimer;

private void ResetTimer()
{
  tmrCtr = 0;
}

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

Quindi, se intendi ripetere ogni secondo, puoi impostare l'intervallo del timer a 100 ms e testare il contatore a 10 cicli.

Questo è adatto se il timer deve attendere alcuni processi che possono essere terminati in un intervallo di tempo diverso.


1

lo faccio

//Restart the timer
queueTimer.Enabled = true;

Questo lo abilita. Anche se è stato disabilitato in precedenza, la riabilitazione non ha modificato il tempo trascorso che era stato raccolto fino a quel punto.
vapcguy

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.