C # Timer o Thread. Dormire

Sto eseguendo un servizio Windows e usando un loop e Thread.Sleep per ripetere un’attività, sarebbe meglio usare un metodo timer?

Se sì, un esempio di codice sarebbe fantastico

Attualmente sto usando questo codice da ripetere

int curMinute; int lastMinute = DateTime.Now.AddMinutes(-1).Minute; while (condition) { curMinute = DateTime.Now.Minute; if (lastMinute < curMinute) { // do your once-per-minute code here lastMinute = curMinute; } Thread.Sleep(50000); // sleeps for 50 seconds if (error condition that would break you out of this) { break; // leaves looping structure } } 

 class Program { static void Main(string[] args) { Timer timer = new Timer(new TimerCallback(TimeCallBack),null,1000,50000); Console.Read(); timer.Dispose(); } public static void TimeCallBack(object o) { curMinute = DateTime.Now.Minute; if (lastMinute < curMinute) { // do your once-per-minute code here lastMinute = curMinute; } } 

Il codice potrebbe somigliare a qualcosa come quello sopra

Un timer è un’idea migliore, IMO. In questo modo, se il tuo servizio viene richiesto di interromperlo, può rispondere a questo molto rapidamente e non chiamare nuovamente il gestore di tick del timer … se stai dormendo, il gestore del servizio dovrà attendere 50 secondi o uccidere il tuo filo, nessuno dei quali è terribilmente bello.

È importante capire che il tuo codice dormirà per 50 secondi tra la fine di un ciclo e l’avvio del prossimo …

Un timer chiamerà il tuo loop ogni 50 secondi, che non è esattamente lo stesso.

Sono entrambi validi, ma un timer è probabilmente quello che stai cercando qui.

Attenzione che chiamare Sleep () bloccherà il servizio, quindi se il servizio viene richiesto di interromperlo, non risponderà per la durata della chiamata Sleep ().

Sì, l’uso di un timer consente di liberare un thread che sta attualmente trascorrendo la maggior parte del suo tempo dormendo. Un timer farà anche fuoco più accuratamente ogni minuto, quindi probabilmente non avrai più bisogno di tenere traccia di lastMinute .

Non rispondere abbastanza alla domanda, ma piuttosto che avere

  if (error condition that would break you out of this) { break; // leaves looping structure } 

Probabilmente dovresti averlo

 while(!error condition) 

Inoltre, andrei con un Timer .

Ho usato entrambi i timer e Thread.Sleep (x), o entrambi, a seconda della situazione.

Se ho un breve pezzo di codice che deve essere eseguito in modo irregolare, probabilmente utilizzo un timer.

Se ho un pezzo di codice che potrebbe impiegare più tempo del timer di ritardo (come il recupero di file da un server remoto via FTP, dove non controllo o non conosco il ritardo della rete o le dimensioni / conteggio dei file), aspetterò per un periodo di tempo fisso tra i cicli.

Entrambi sono validi, ma come sottolineato in precedenza fanno cose diverse. Il timer esegue il tuo codice ogni x millisecondi, anche se l’istanza precedente non è stata completata. Thread.Sleep (x) attende un periodo di tempo dopo aver completato ciascuna iterazione, quindi il ritardo totale per ciclo sarà sempre più lungo (forse non di molto) rispetto al periodo di sospensione.

Ho richiesto un thread per sparare una volta ogni minuto ( vedi domanda qui ) e ora ho usato un DispatchTimer base alle risposte che ho ricevuto.

Le risposte forniscono alcuni riferimenti che potresti trovare utili.

Sono d’accordo pure, usare un timer è l’opzione migliore. Ho provato una soluzione simile alla tua in passato e ho iniziato ad avere problemi in cui il loop si sarebbe infilato e dovevo aspettare un altro Thread.Sleep () prima che potesse sparare di nuovo. Inoltre, ha causato tutti i tipi di problemi con l’arresto del servizio, vorrei ottenere errori costanti su come non rispondeva e dovevo essere chiuso.

@ Il codice di Prashanth dovrebbe essere esattamente ciò di cui hai bisogno.

Puoi usare uno dei due. Ma penso che Sleep() sia facile, chiaro e breve da implementare.

Dovrei dire che dormire è un’implementazione migliore con una macchina statale dietro. Ciò ti manterrà comunque in controllo dell’applicazione in qualsiasi momento, ma consentirà qualsiasi risposta necessaria in qualsiasi momento specifico. Questo gestirà anche i callback del timer più brevi di “Elaborazione del tempo di esecuzione nel loop”

Per esempio..

  public enum State { Idle = 0, Processing = 1, Stop = 100, } public void Run() { State state = State.Idle; // could be a member variable, so a service could stop this too double intervalInSeconds = 60; System.DateTime nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds); while (state != State.Stop) { switch (state) { case State.Idle: { if (nextExecution > System.DateTime.Now) { state = State.Processing; } } break; case State.Processing: { // do your once-per-minute code here // if you want it to stop, just set it state to stop. // if this was a service, you could stop execution by setting state to stop, also // only time it would not stop is if it was waiting for the process to finish, which you can handle in other ways state = State.Idle; nextExecution = System.DateTime.Now.AddSeconds(intervalInSeconds); } break; default: break; } System.Threading.Thread.Sleep(1); } }