J'exécute un service Windows et j'utilise une boucle et Thread.Sleep pour répéter une tâche, serait-il préférable d'utiliser une méthode de minuterie?
Si oui, un exemple de code serait parfait
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(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;
}
}
Le code pourrait ressembler à quelque chose comme celui ci-dessus
Une minuterie est une meilleure idée, OMI. De cette façon, si votre service est invité à s'arrêter, il peut y répondre très rapidement, et ne pas appeler à nouveau le gestionnaire de ticks du minuteur ... si vous dormez, le gestionnaire de service devra soit attendre 50 secondes, soit tuer votre fil, ni l'un ni l'autre n'est terriblement gentil.
Il est important de comprendre que votre code dormira pendant 50 secondes entre la fin d'une boucle et le démarrage de la suivante ...
Une minuterie appellera votre boucle toutes les 50 secondes, ce qui n'est pas exactement la même chose.
Ils sont tous les deux valides, mais une minuterie est probablement ce que vous recherchez ici.
Attention, appeler Sleep () gèrera 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 minuterie libérera un fil qui passe actuellement la plupart de son temps à dormir. Une minuterie se déclenchera également plus précisément toutes les minutes, vous n'aurez donc probablement plus besoin de suivre 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 auriez probablement dû
while(!error condition)
Aussi, j'irais avec un Timer
.
J'ai utilisé à la fois des minuteries et Thread.Sleep (x), ou les deux, selon la situation.
Si j'ai un petit morceau de code qui doit s'exécuter de façon répétée, j'utilise probablement une minuterie.
Si j'ai un morceau de code qui peut prendre plus de temps à exécuter que le temporisateur de délai (comme la récupération de fichiers à partir d'un serveur distant via FTP, où je ne contrôle pas ou ne connais pas le délai réseau ou la taille/le nombre de fichiers), j'attendrai pendant une période de temps fixe 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 pendant un certain temps après avoir terminé chaque itération, donc le retard total par boucle sera toujours plus long (peut-être pas beaucoup) que la période de sommeil.
J'avais 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 quelques références que vous pourriez trouver utiles.
Je suis également d'accord, l'utilisation d'une minuterie est la meilleure option. J'ai essayé une solution similaire à la vôtre dans le passé et j'ai commencé à avoir des problèmes où la boucle se ratait, et je devais attendre un autre Thread.Sleep () avant de se déclencher à nouveau. De plus, cela a causé toutes sortes de problèmes avec l'arrêt du service, j'obtiendrais 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 à implémenter.