121 votes

Service Windows et tâche planifiée

Quels sont les avantages et les inconvénients des services Windows par rapport aux tâches planifiées pour l'exécution répétée d'un programme (par exemple, toutes les deux minutes) ?

71voto

Mark Ransom Points 132545

Il y a une comparaison bien raisonnée ici :

http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx

En résumé, les tâches planifiées sont généralement préférées aux services Windows.

53voto

Junto Points 5597

Mise à jour :

Près de quatre ans après ma réponse initiale et cette réponse est très obsolète. Depuis TopShelf est arrivé, le développement des services Windows est devenu facile. Il ne vous reste plus qu'à trouver comment supporter le basculement...

Réponse originale :

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

L'autre inconvénient majeur de Windows Scheduler est qu'il fonctionne 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 en voudrez de ne pas les avoir installées en tant que services Windows.

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

Vous constaterez que la programmation d'un service Windows n'est pas une partie de plaisir. Un scénario assez courant est celui d'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 travailleur traitent la même file d'attente. Vous devez donc gérer la minuterie, afin de vous assurer que si votre processus long s'est exécuté plus longtemps que l'intervalle de minuterie assigné, il ne redémarre pas avant que le processus existant ne soit terminé.

Après avoir écrit tout cela, vous vous dites : pourquoi n'ai-je pas simplement utilisé Thread.Sleep ? Cela me permet de laisser le thread en cours d'exécution jusqu'à ce qu'il ait terminé, puis l'intervalle de pause se déclenche, le thread se met en sommeil et redémarre après le temps requis. C'est génial !

Vous lisez ensuite tous les conseils sur l'internet, où de nombreux experts vous disent que 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 grattez la tête et vous vous dites : "WTF, annuler les caisses en attente -> Oui, je suis sûr -> annuler tout le travail d'aujourd'hui..... damn, damn, damn....".

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 à fil unique.

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 attache notre travailleur à celui-ci. Ensuite, il démarre le thread et laisse l'événement OnStart se terminer, afin que Windows ne pense pas que le service est suspendu.

Méthode de travail pour l'approche à fil unique.

/// <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 à fil unique.

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

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

Je fais fonctionner de nombreux services Windows de cette manière depuis des années et cela me convient parfaitement. Je n'ai toujours pas vu de modèle recommandé sur lequel les gens sont d'accord. Faites simplement ce qui fonctionne pour vous.

2 votes

En réalité, vous pourriez vouloir exécuter votre service avec son propre compte de service. Si tout fonctionne avec un compte SERVICE ou NETWORKSERVICE, vous accordez à votre application des permissions dont elle n'a probablement pas besoin (et cela peut mettre en péril la sécurité non seulement d'un seul serveur, mais aussi de tout votre réseau).

1 votes

En effet. Je ne pense pas avoir dit le contraire ?

4 votes

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.

17voto

Amit Naidu Points 876

Quelques informations erronées ici. Le planificateur Windows est parfaitement capable d'exécuter des tâches en arrière-plan sans que Windows n'apparaisse et sans mot de passe. Exécutez-le sous l'AUTORITÉ NT \SYSTEM compte. Utilisez ce commutateur schtasks :

/ru SYSTEM

Mais oui, pour l'accès aux ressources du réseau, la meilleure pratique est un compte de service avec une politique distincte de mot de passe non expirant.

EDITAR

En fonction de votre système d'exploitation et des exigences de la tâche elle-même, vous pouvez être en mesure d'utiliser des comptes moins privilégiés que Localsystem avec la commande /ru option.

De l'amende 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.

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

Dans XP et Server 2003, system est la seule option.

2 votes

Veuillez exécuter en tant que Local Service (alias NT AUTHORITY\LocalService ) plutôt que LocalSystem (alias .\LocalSystem ). Le premier a des droits limités, tandis que le second est un administrateur.

1 votes

Oui, les comptes supplémentaires LocalService y NetworkService sont disponibles dans schtasks v2 Vista et suivantes et devraient être préférées lorsque cela est possible. À l'époque, cela faisait référence à la schtasks dans XP et Server 2003 qui n'acceptent que le System comme paramètre selon le manuel de l'ancienne version technet.microsoft.com/fr/us/library/bb490996.aspx

0 votes

Sous XP, vous ne pouvez pas exécuter une tâche planifiée en tant que SYSTÈME. Bonne chance avec cela. Celui-ci résume bien la situation : cwl.cc/2011/12/exploitation-scheduled-task-as-system.html

13voto

moodforaday Points 2633

Quels sont les frais généraux liés au démarrage et à l'arrêt de l'application ? Toutes les deux minutes, c'est assez fréquent. Un service permettrait probablement au système de fonctionner de manière plus fluide qu'en exécutant votre application aussi fréquemment.

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

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

4voto

Mark Ransom Points 132545

Il n'est pas nécessaire que quelqu'un soit connecté à un service Windows, et ce dernier dispose de moyens 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.

9 votes

Les tâches planifiées peuvent également être exécutées sans que l'utilisateur soit connecté, mais le mot de passe de l'utilisateur doit être fourni à l'agent de planification.

1 votes

@moodforaday Sauf si le compte n'a pas été configuré (par ex. NT AUTHORITY\LocalService o NT AUTHORITY\NetworkService ). Tout mot de passe fourni est ignoré car les comptes n'ont pas de mot de passe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X