service Windows vs tâche planifiée

115

Quels sont les inconvénients et les avantages des services Windows par rapport aux tâches planifiées pour exécuter un programme à plusieurs reprises (par exemple toutes les deux minutes)?

Manu
la source

Réponses:

51

Mettre à jour:

Près de quatre ans après ma réponse initiale et cette réponse est très dépassée. Depuis l' arrivée de TopShelf , le développement des services Windows est devenu facile. Il ne vous reste plus qu'à comprendre comment prendre en charge le basculement ...

Réponse originale:

Je ne suis vraiment pas fan de Windows Scheduler. Le mot de passe de l'utilisateur doit être fourni comme @moodforall souligne ci-dessus, ce qui est amusant lorsque quelqu'un change le mot de passe de cet utilisateur.

L'autre inconvénient majeur du planificateur Windows est qu'il s'exécute de manière interactive et non en tant que processus d'arrière-plan. Lorsque 15 fenêtres MS-DOS apparaissent toutes les 20 minutes pendant une session RDP, vous vous coupez qui ne les a pas installées en tant que services Windows à la place.

Quoi que vous choisissiez, je vous recommande certainement de séparer votre code de traitement en un composant différent de l'application console ou du service Windows. Ensuite, vous avez le choix, soit d'appeler le processus de travail à partir d'une application console et de le connecter au planificateur Windows, soit d'utiliser un service Windows.

Vous constaterez que planifier un service Windows n'est pas amusant. Un scénario assez courant est que vous avez un processus de longue durée que vous souhaitez exécuter périodiquement. Mais, si vous traitez une file d'attente, vous ne voulez vraiment pas que deux instances du même worker traitent la même file d'attente. Vous devez donc gérer la minuterie, pour vous assurer que si votre processus de longue durée a duré plus longtemps que l'intervalle de minuterie attribué, il ne redémarre pas tant que le processus existant n'est pas terminé.

Après avoir écrit tout cela, vous pensez, pourquoi n'ai-je pas simplement utilisé Thread.Sleep? Cela me permet de laisser le thread actuel continuer à fonctionner jusqu'à ce qu'il soit terminé, puis l'intervalle de pause entre en action, le thread se met en veille et redémarre après le temps requis. Soigné!

Ensuite, vous lisez tous les conseils sur Internet avec de nombreux experts vous disant à quel point c'est une très mauvaise pratique de programmation:

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

Alors vous vous gratterez la tête et vous penserez à vous-même, WTF, Annuler les contrôles en attente -> Oui, j'en suis sûr -> Annuler tout le travail d'aujourd'hui ..... putain, putain, putain ....

Cependant, j'aime ce modèle, même si tout le monde pense que c'est de la merde:

Méthode OnStart pour l'approche à un seul thread.

protected override void OnStart (string args) {

   // Create worker thread; this will invoke the WorkerFunction
   // when we start it.
   // Since we use a separate worker thread, the main service
   // thread will return quickly, telling Windows that service has started
   ThreadStart st = new ThreadStart(WorkerFunction);
   workerThread = new Thread(st);

   // set flag to indicate worker thread is active
   serviceStarted = true;

   // start the thread
   workerThread.Start();
}

Le code instancie un thread séparé et y attache notre fonction de travail. Ensuite, il démarre le thread et laisse l'événement OnStart se terminer, de sorte que Windows ne pense pas que le service est bloqué.

Méthode de travail pour l'approche à un seul thread.

/// <summary>
/// This function will do all the work
/// Once it is done with its tasks, it will be suspended for some time;
/// it will continue to repeat this until the service is stopped
/// </summary>
private void WorkerFunction() {

   // start an endless loop; loop will abort only when "serviceStarted"
   // flag = false
   while (serviceStarted) {

      // do something
      // exception handling omitted here for simplicity
      EventLog.WriteEntry("Service working",
         System.Diagnostics.EventLogEntryType.Information);

      // yield
      if (serviceStarted) {
         Thread.Sleep(new TimeSpan(0, interval, 0));
      }
   }

   // time to end the thread
   Thread.CurrentThread.Abort();
}

Méthode OnStop pour l'approche à un seul thread.

protected override void OnStop() {

   // flag to tell the worker process to stop
   serviceStarted = false;

   // give it a little time to finish any pending work
   workerThread.Join(new TimeSpan(0,2,0));
}

Source: http://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (lien mort)

J'exécute beaucoup de services Windows comme celui-ci depuis des années et cela fonctionne pour moi. Je n'ai toujours pas vu de modèle recommandé sur lequel les gens sont d'accord. Faites simplement ce qui fonctionne pour vous.

Rebecca
la source
2
Vous voudrez peut-être vraiment exécuter votre service avec son propre compte de service. Si tout exécute un SERVICE ou un NETWORKSERVICE, vous accordez à votre application des autorisations dont elle n'a probablement pas besoin (et cela peut mettre en danger la sécurité non seulement d'un serveur, mais de l'ensemble de votre réseau.)
Matthew Whited
1
En effet. Je ne pense pas avoir dit le contraire?
Rebecca
4
Vous avez en quelque sorte laissé entendre le contraire dans votre premier paragraphe. Le mot de passe de l'utilisateur est requis pour les services de la même manière que pour le planificateur de tâches si vous n'utilisez pas l'un des comptes intégrés.
Nick Cox
1
@MatthewWhited NT AUTHORITY\NetworkServiceest un compte avec des privilèges limités.
Ian Boyd
1
@IanBoyd, y compris toute autorisation attribuée à NetworkService liée à d'autres applications.
Matthew Whited
16

Une certaine désinformation ici. Windows Scheduler est parfaitement capable d'exécuter des tâches en arrière-plan sans que les fenêtres n'apparaissent et sans mot de passe requis. Exécutez-le sous le compte NT AUTHORITY \ SYSTEM. Utilisez ce commutateur schtasks:

/ ru SYSTÈME

Mais oui, pour accéder aux ressources réseau, la meilleure pratique est un compte de service avec une stratégie de mot de passe non expirante distincte.

ÉDITER

Selon votre système d'exploitation et les exigences de la tâche elle-même, vous pourrez peut-être utiliser des comptes moins privilégiés que Localsystem avec le /ru option.

Du beau manuel ,

/RU username

A value that specifies the user context under which the task runs. 
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM". 
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and 
"NT AUTHORITY\NETWORKSERVICE" are also valid values.

Le planificateur de tâches 2.0 est disponible à partir de Vista et Server 2008.

Dans XP et Server 2003, systemc'est la seule option.

Amit Naidu
la source
2
Veuillez exécuter en tant que Local Service(aka NT AUTHORITY\LocalService) plutôt que LocalSystem(aka .\LocalSystem). Le premier a des droits limités, tandis que le second est administrateur
Ian Boyd
1
Oui, les comptes supplémentaires LocalServiceet NetworkServicesont disponibles à partir de schtasksv2 Vista et devraient être préférés dans la mesure du possible. À l'époque, cela faisait référence à schtasksXP et Server 2003 qui n'acceptent que le Systemcomme paramètre selon l'ancienne version du manuel technet.microsoft.com/en-us/library/bb490996.aspx
Amit Naidu
Sur XP, vous ne pouvez pas exécuter la tâche planifiée en tant que SYSTEM. Bonne chance avec ça. Celui-ci résume bien: cwl.cc/2011/12/run-scheduled-task-as-system.html
Pupsik
11

Quels sont les frais généraux liés au démarrage et à la fermeture de l'application? Toutes les deux minutes, c'est assez souvent. Un service permettrait probablement au système de fonctionner plus facilement que d'exécuter votre application si fréquemment.

Les deux solutions peuvent exécuter le programme lorsque l'utilisateur n'est pas connecté, donc aucune différence. Cependant, l'écriture d'un service est un peu plus complexe qu'une application de bureau classique - vous pouvez avoir besoin d'un client GUI séparé qui communiquera avec l'application de service via TCP / IP, des canaux nommés, etc.

Depuis le point de vue d'un utilisateur, je me demande lequel est le plus facile à contrôler. Les services et les tâches planifiées sont à peu près hors de portée pour la plupart des utilisateurs non techniques, c'est-à-dire qu'ils ne se rendront même pas compte qu'ils existent et peuvent être configurés / arrêtés / reprogrammés et ainsi de suite.

Marek Jedliński
la source
10

Dans le développement .NET, je commence normalement par développer une application console, qui exécutera toutes les sorties de journalisation dans la fenêtre de la console. Cependant, il s'agit uniquement d' une application console lorsqu'elle est exécutée avec l'argument de commande /console. Lorsqu'il est exécuté sans ce paramètre, il agit comme un service Windows, qui restera en cours d'exécution sur mon propre minuteur programmé codé personnalisé.

Je pense que les services Windows sont normalement utilisés pour gérer d'autres applications, plutôt que pour être une application de longue durée. OU .. ils exécutent en permanence des applications lourdes comme SQL Server, BizTalk, RPC Connections, IIS (même si IIS décharge techniquement le travail vers d'autres processus).

Personnellement, je préfère les tâches planifiées aux services Windows pour les tâches de maintenance répétitives et les applications telles que la copie / synchronisation de fichiers, l'envoi d'e-mails en masse, la suppression ou l'archivage de fichiers, la correction des données (lorsque d'autres solutions de contournement ne sont pas disponibles).

Pour un projet, j'ai été impliqué dans le développement de services Windows 8 ou 9, mais ceux-ci restent en mémoire, inactifs, consommant 20 Mo ou plus de mémoire par instance. Les tâches planifiées feront leur travail et libéreront la mémoire immédiatement.

Dominic Zukiewicz
la source
8

Le mot 'serv'ice a quelque chose en commun avec' serv'er. On s'attend à ce qu'il soit toujours en cours d'exécution, et 'serv'e. Une tâche est une tâche.

Jeu de rôle. Si je suis un autre système d'exploitation, une autre application ou un autre appareil et que j'appelle un service, je m'attends à ce qu'il fonctionne et j'attends une réponse. Si je (os, app, dev) juste besoin d'exécuter une tâche isolée, alors j'exécuterai une tâche, mais si je prévois de communiquer, éventuellement une communication bidirectionnelle, je veux un service. Cela a à voir avec le moyen le plus efficace pour deux choses de communiquer, ou une seule chose qui veut exécuter une seule tâche.

Ensuite, il y a l'aspect de la planification. Si vous voulez que quelque chose s'exécute à une heure précise, planifiez. Si vous ne savez pas quand vous en aurez besoin, ou quand vous en aurez besoin "à la volée", faites un service.

Ma réponse est de nature plus philosophique car c'est très similaire à la façon dont les humains interagissent et travaillent avec les autres. Plus nous comprenons l'art de la communication et les «entités» comprennent leur rôle, plus cette décision devient facile.

Toute philosophie mise à part, lorsque vous «prototypez rapidement», comme le fait souvent mon département informatique, vous faites tout ce que vous devez pour joindre les deux bouts. Une fois que le prototypage et la preuve de concept sont éliminés, généralement au début de la planification et de la découverte, vous devez décider de ce qui est le plus fiable pour la durabilité à long terme.

OK, donc en conclusion, cela dépend fortement de nombreux facteurs, mais j'espère que cela a fourni un aperçu au lieu de la confusion.

Dan Cortese
la source
4

Un service Windows n'a pas besoin que quelqu'un se connecte, et Windows dispose de fonctionnalités pour arrêter, démarrer et enregistrer les résultats du service.

Une tâche planifiée ne nécessite pas que vous appreniez à écrire un service Windows.

Mark Ransom
la source
9
Les tâches planifiées peuvent également s'exécuter sans que l'utilisateur soit connecté, mais le mot de passe de l'utilisateur doit être fourni à l'agent de planification.
Marek Jedliński
1
@moodforaday Sauf si le compte n'a pas été configuré (par exemple NT AUTHORITY\LocalService, ou NT AUTHORITY\NetworkService). Tout mot de passe fourni est ignoré car les comptes n'ont pas de mot de passe.
Ian Boyd
4
  1. Il est plus facile de configurer et de verrouiller les services Windows avec les autorisations appropriées.
  2. Les services sont plus «visibles», ce qui signifie que tout le monde (c'est-à-dire les techniciens) sait où chercher.
Pas moi
la source
5
Votre premier point s'applique également aux tâches planifiées. Je ne sais pas trop ce que signifie «plus visible». Les tâches planifiées peuvent être visualisées aussi simplement que les services.
w4g3n3r
@ w4g3n3r: La plupart des techniciens savent comment regarder les services Windows pour voir ce qui fonctionne. De plus, s'il s'agit d'un service (et en cours d'exécution), il apparaîtra dans la liste normale du gestionnaire de tâches. Très peu de personnes utilisent des tâches planifiées.
NotMe
De plus, les techniciens savent qu'il faut regarder dans l'observateur d'événements en cas de problème. Les tâches planifiées stockent ces informations dans un fichier journal sur le système de fichiers. Je suis prêt à parier que la plupart des gens ne sauraient même pas où chercher cela.
NotMe
1
Je ne suis pas d'accord sur "Très très peu de gens utilisent des tâches planifiées" à moins que vous n'ayez des statistiques. Je les vois tout le temps. Pour les non-codeurs qui ont besoin d'exécuter quelque chose toutes les 2 minutes, ils naviguent simplement vers les tâches planifiées (même difficulté que pour accéder aux services), mais pour en créer un nouveau, il existe un assistant. Il leur suffit donc de savoir où se trouve le programme ou le script et à quelle fréquence il doit s'exécuter. Maintenant, si vous savez coder et que la machine est sur un réseau, que vous avez besoin de protéger la connexion, que vous avez besoin d'une gestion intégrée pour empêcher plusieurs instances (si l'une fonctionne sur 2 minutes), alors j'irais avec un service.
Gary
4
"La plupart des techniciens savent comment regarder les services Windows pour voir ce qui fonctionne" . C'est l'un des problèmes des services; ils exécutent toutes les ressources de l'utilisateur et du noyau qui prennent du temps simplement pour la tenue de livres d'un processus en cours d'exécution. C'est pourquoi Microsoft a fusionné autant de services que possible en un seul processus ( svchost.exe ); pour supprimer la consommation inutile de ressources simplement en ayant des processus.
Ian Boyd
2

Pourquoi ne pas fournir les deux?

Dans le passé, j'ai mis les bits `` principaux '' dans une bibliothèque et enveloppé un appel à Whatever.GoGoGo () à la fois dans un service et dans une application console.

Avec quelque chose que vous déclenchez toutes les deux minutes, les chances sont bonnes, il ne fait pas grand-chose (par exemple juste une fonction de type "ping"). Les wrappers ne devraient pas avoir à contenir beaucoup plus qu'un simple appel de méthode et une certaine journalisation.


la source
2

C'est une vieille question mais j'aimerai partager ce à quoi j'ai été confronté.

Récemment, on m'a demandé de capturer la capture d'écran d'un radar (à partir d'un site Web météorologique) et de l'enregistrer sur le serveur toutes les 10 minutes.

Cela m'a obligé à utiliser WebBrowser. Je fais généralement des services Windows, j'ai donc décidé de créer ce service, mais il continuerait à planter. C'est ce que j'ai vu dans le chemin du module défaillant de l'Observateur d' événements : C: \ Windows \ system32 \ MSHTML.dll

Comme la tâche était urgente et que j'avais très moins de temps pour rechercher et expérimenter, j'ai décidé d'utiliser une simple application console et l'ai déclenchée comme une tâche et elle s'est exécutée sans problème.

J'ai beaucoup aimé l' article de Jon Galloway recommandé dans la réponse acceptée par Mark Ransom.

Récemment, les mots de passe sur les serveurs ont été modifiés sans me reconnaître et tous les services n'ont pas pu s'exécuter car ils ne pouvaient pas se connecter. Donc, ppl prétendant dans l'article commente que c'est un problème. Je pense que les services Windows peuvent faire face au même problème (veuillez me corriger si je me trompe, je suis juste un débutant)

Aussi la chose mentionnée, si vous utilisez les fenêtres du planificateur de tâches ou la fenêtre de la console apparaît. Je n'ai jamais fait face à ça. Cela peut apparaître mais c'est au moins très instantané.

argent
la source
Je pensais que l'article de Jon Galloway présentait de bons points. En outre, pour la plainte concernant l'échec de l'exécution des tâches planifiées en raison d'un changement de mot de passe ou autre, il est possible de répondre à une tâche planifiée dont l'exécution échoue, afin que vous puissiez informer les utilisateurs ou tout ce que vous souhaitez faire. Voir la solution ici: superuser.com/questions/249103/…
Dan Csharpster
1

Généralement, le message principal est et devrait être que le code lui-même doit être exécutable à partir de chaque "déclencheur / client". Il ne devrait donc pas être sorcier de passer de l’une à l’autre.

Dans le passé, nous utilisions plus ou moins toujours les services Windows, mais depuis aussi de plus en plus de nos clients passent à Azure étape par étape et le passage d'une application console (déployée en tant que tâche planifiée) à un WebJob dans Azure est beaucoup plus facile que de un service Windows, nous nous concentrons sur les tâches planifiées pour le moment. Si nous rencontrons des limitations, nous accélérons simplement le projet de service Windows et appelons la même logique à partir de là (tant que les clients travaillent OnPrem ..) :)

BR, y

ynnok
la source
0

Les services Windows veulent plus de patience jusqu'à ce que ce soit fait. Il a un débogage et une installation un peu difficiles. C'est sans visage. Si vous avez besoin d'une tâche qui doit être effectuée toutes les secondes, minutes ou heures, vous devez choisir Windows Service.

La tâche planifiée est rapidement développée et a un visage. Si vous avez besoin d'une tâche quotidienne ou hebdomadaire, vous pouvez utiliser Tâche planifiée.

Oguzhan KIRCALI
la source