web-dev-qa-db-fra.com

Minuterie C # ou filetage.

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
   }
}
45
Adonis L
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

32
Prashanth

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.

43
Jon Skeet

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.

11
Christopher Karper

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 ().

7
Philippe Leybaert

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.

4
Jon Norton

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.

2
cjk

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.

1
jwhitley

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.

1
Simon Temlett

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.

0
Nick DeMayo

Vous pouvez utiliser l'un ou l'autre. Mais je pense que Sleep() est facile, clair et plus court à implémenter.

0
Umair Ahmed