Minuterie C # ou fil. Dormir

Je cours un service Windows et utilise une boucle et Thread.Sleep pour répéter une tâche, serait-il préférable d’utiliser une méthode de timer?

Si oui, un exemple de code serait génial

J’utilise actuellement ce code pour répéter

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(ssortingng[] 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; } } 

Le code pourrait ressembler à celui ci-dessus

Une timer est une meilleure idée, IMO. De cette façon, si votre service est invité à s’arrêter, il peut répondre très rapidement et ne pas appeler le gestionnaire de timer à nouveau … si vous dormez, le gestionnaire de service devra attendre 50 secondes ou tuer votre ordinateur. thread, ni l’un ni l’autre n’est terriblement gentil.

Il est important de comprendre que votre code va dormir pendant 50 secondes entre la fin d’une boucle et le début de la prochaine …

Une timer appellera votre boucle toutes les 50 secondes, ce qui n’est pas exactement la même chose.

Ils sont tous deux valides, mais une timer est probablement ce que vous cherchez ici.

Attention, l’appel de Sleep () gèle le service, donc si le service est invité à s’arrêter, il ne réagira pas pendant la durée de l’appel Sleep ().

Oui, l’utilisation d’une timer libère un thread qui passe le plus clair de son temps à dormir. Un minuteur déclenchera également plus précisément chaque minute afin que vous n’ayez probablement plus besoin de suivre la dernière lastMinute .

Pas tout à fait répondre à la question, mais plutôt que d’avoir

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

Vous devriez probablement avoir

 while(!error condition) 

Aussi, j’irais avec une Timer .

J’ai utilisé les deux minuteurs et Thread.Sleep (x), ou l’un ou l’autre, selon la situation.

Si j’ai un petit bout de code qui doit être répété, j’utilise probablement une timer.

Si j’ai un morceau de code qui peut prendre plus de temps à exécuter que le temporisateur (comme récupérer des fichiers à partir d’un serveur distant via FTP, où je ne contrôle pas ou ne connaît pas le délai réseau ou la taille / nombre de fichiers), j’attendrai pour une période de temps déterminée entre les cycles.

Les deux sont valables, mais comme indiqué précédemment, ils font des choses différentes. Le minuteur exécute votre code toutes les x millisecondes, même si l’instance précédente n’est pas terminée. Le thread.Sleep (x) attend une période de temps après chaque itération, de sorte que le délai total par boucle sera toujours plus long (peut-être pas beaucoup) que la période de sumil.

J’ai eu besoin d’un thread pour tirer une fois par minute ( voir la question ici ) et j’ai maintenant utilisé un DispatchTimer basé sur les réponses que j’ai reçues.

Les réponses fournissent des références que vous pourriez trouver utiles.

Je suis également d’accord, l’utilisation d’une timer est la meilleure option. J’ai déjà essayé une solution similaire à la vôtre et j’ai commencé à avoir des problèmes où la boucle ne fonctionnait pas correctement, et je devais attendre un autre Thread.Sleep () avant qu’il ne se déclenche à nouveau. En outre, cela a causé toutes sortes de problèmes avec l’arrêt du service, je recevais des erreurs constantes sur la façon dont il ne répondait pas et devait être fermé.

Le code de @ Prashanth devrait être exactement ce dont vous avez besoin.

Vous pouvez utiliser l’un ou l’autre. Mais je pense que Sleep() est facile, clair et plus court à mettre en œuvre.

Je dirais qu’un sumil est une meilleure implémentation avec une machine à états. Cela vous permettrait de garder le contrôle de l’application à tout moment, mais en autorisant toute réponse nécessaire à un moment donné. Cela permettra également de gérer les rappels de temporisation qui sont plus courts que le “Temps d’exécution du traitement dans la boucle”

Par exemple..

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