2009-06-15 10 views
12

J'écris un service Windows qui doit dormir pendant de longues périodes (15 heures est le plus long, 30 minutes est le plus court). J'utilise actuellement Thread.Sleep (calculateTime) pour mettre mon code en mode veille. Thread.Sleep est la meilleure option ou devrais-je utiliser une minuterie? J'ai été googling cela pendant un moment et ne peux pas trouver une réponse concise. Comme il s'agit d'un service Windows, je n'ai pas à m'inquiéter de verrouiller l'interface utilisateur, donc je ne peux pas penser à une raison pour ne pas utiliser Thread.Sleep.Utilisation de Thread.Sleep() dans un service Windows

Tout aperçu serait apprécié.

Répondre

19

Je voudrais utiliser une minuterie, Thread.Sleep, pourrait provoquer une pièce de blocage qui pourrait empêcher l'arrêt du service.

Si l'intervalle est aussi large et régulier, vous pouvez également le programmer. Mais si vous parlez d'intervalles longs et non cohérents, alors oui, une minuterie serait préférable.

7

Il est généralement considéré comme une mauvaise pratique d'utiliser Thread.Sleep() dans beaucoup de cas.

Si vous souhaitez que le service s'exécute en arrière-plan, vous devez utiliser une minuterie. Si le service doit uniquement être exécuté à des intervalles planifiés, nous vous recommandons d'utiliser le planificateur de tâches Windows pour permettre à Windows d'exécuter l'application lorsque vous en avez besoin.

5

Vous ne devriez pas pré-calculer de telles quantités de temps et dormir pendant des heures. Dormez au mieux pendant une minute, puis réveillez-vous et recalculez l'heure, dormez à nouveau pour ne plus qu'une minute. Je suppose que le calcul est très bon marché ou il peut être fait très bon marché avec la mise en cache. Le problème que mon conseiller essaye d'atténuer est que les horloges d'ordinateur sont étonnamment «nerveux», principalement en raison de la dérive temporelle corrigée par le service de temps de réseau, également en raison des économies de jour et non parce que l'utilisateur ajuste l'horloge. Il est donc préférable de constamment recalculer le temps pour de si longs intervalles, même si cela signifie se réveiller à chaque minute. Et ne soyez pas surpris (c'est-à-dire ne l'affirmez pas) si vous vous réveillez dans le «passé», les horloges peuvent s'ajuster dans le temps.

1

Une autre chose à considérer est que les threads sont des ressources finies et chaque thread consomme une partie de la mémoire (1 Mo?) Pour sa pile. Ils peuvent également augmenter la charge pour le planificateur. Maintenant, si votre service ne fait pas grand chose d'autre, l'espace gaspillé est trivial, mais il est sage d'en être conscient avant de commencer à allouer plusieurs threads. L'utilisation d'un ThreadPool et/ou de Timers est beaucoup plus efficace.

9

Puisqu'un service peut être invité à s'arrêter à tout moment par le Gestionnaire de contrôle des services, votre thread doit toujours être prêt à répondre à ces demandes, vous ne devez donc pas utiliser Thread.Sleep(). Au lieu de cela, créez un événement de réinitialisation manuelle dans le thread principal et utilisez sa méthode WaitOne avec un délai d'expiration dans votre thread de travail. WaitOne retournera faux quand le temps expire. Lorsque les méthodes OnStop ou OnShutdown de votre classe de service sont appelées, définissez l'événement et WaitOne renvoie true et vous pouvez alors quitter votre thread de travail.

Questions connexes