Quels sont les inconvénients et les avantages 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)?
Mettre à jour:
Près de quatre ans après ma réponse initiale et cette réponse est très obsolète. Depuis que TopShelf est arrivé, 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 un fan de Windows Scheduler. Le mot de passe de l'utilisateur doit être fourni sous la forme @moodforall indique ci-dessus, ce qui est amusant lorsque quelqu'un modifie 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 arrière-plan. Lorsque 15 fenêtres MS-DOS apparaissent toutes les 20 minutes au cours d'une session RDP, vous ne pouvez plus les installer en tant que services Windows.
Quoi que vous choisissiez, je vous recommande certainement de séparer votre code de traitement en un composant différent de l'application de la console ou du service Windows. Vous avez ensuite le choix d'appeler le processus de travail à partir d'une application console et de le connecter au planificateur Windows ou d'utiliser un service Windows.
Vous constaterez que la planification d'un service Windows n'est pas amusant. Un scénario assez courant est que vous souhaitez exécuter périodiquement un processus de longue durée. Toutefois, si vous traitez une file d'attente, vous ne voulez vraiment pas que deux instances du même opérateur traitent la même file d'attente. Il est donc nécessaire de gérer le minuteur pour s'assurer que si votre processus long a été exécuté plus longtemps que l'intervalle de minuteur attribué, il ne sera pas relancé avant la fin du processus existant.
Après avoir écrit tout cela, vous vous demandez pourquoi je n’ai pas utilisé Thread.Sleep? Cela me permet de laisser le thread actuel continuer à s'exécuter jusqu'à ce qu'il soit terminé, puis l'intervalle de pause s'active, le thread s'endort et se déclenche à nouveau après le temps requis. Soigné!
Ensuite, vous lisez tous les conseils sur Internet avec de nombreux experts vous expliquant qu’il s’agit d’une très mauvaise pratique de programmation:
Donc, vous vous gratter la tête et penser à vous-même, WTF, Annuler les commandes en attente -> Oui, j'en suis sûr -> Annuler tout le travail d'aujourd'hui ..... putain, putain, putain ...
Cependant, j'aime bien ce modèle, même si tout le monde pense que c'est de la merde:
Méthode OnStart pour l'approche mono-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 attache notre ouvrier fonctionner à elle. Ensuite, il démarre le fil et laisse l'événement OnStart complète, de sorte que Windows ne pense pas que le service est bloqué.
Méthode de travail pour l'approche mono-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 mono-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'utilise 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 juste ce qui fonctionne pour vous.
Un peu de désinformation ici. Windows Scheduler est parfaitement capable d'exécuter des tâches en arrière-plan sans que des fenêtres n'apparaissent et qu'aucun mot de passe ne soit requis. Exécutez-le sous le compte NT AUTHORITY\SYSTEM. Utilisez ce commutateur schtasks:
/ ru SYSTEM
Mais oui, pour accéder aux ressources du réseau, la meilleure pratique consiste à utiliser un compte de service avec une stratégie de mot de passe distincte et non périmée.
MODIFIER
En fonction de votre système d'exploitation et des exigences de la tâche elle-même, vous pourrez peut-être utiliser des comptes moins privilégiés que Localsystem avec l'option /ru
.
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.
Task Scheduler 2.0 est disponible à partir de Vista et Server 2008.
Dans XP et Server 2003, system
est la seule option.
Quel est le coût de démarrage et de fermeture de l'application? Toutes les deux minutes, c'est assez souvent. Un service laisserait probablement le système fonctionner plus facilement que d’exécuter votre application aussi souvent.
Les deux solutions peuvent exécuter le programme lorsque l'utilisateur n'est pas connecté, donc aucune différence. L'écriture d'un service est un peu plus complexe qu'une application de bureau classique. Cependant, vous aurez peut-être besoin d'un client graphique distinct qui communiquera avec l'application de service via TCP/IP, des canaux nommés, etc.
À partir du point de vue d'un utilisateur, je me demande ce qui est le plus facile à contrôler. Les services et les tâches planifiées sont quasiment 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/replanifiés, etc.
Dans le développement .NET, je commence normalement par développer une application console, qui sera exécutée en consignant toutes les sorties dans la fenêtre de la console. Cependant, il s'agit de seulement / 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 en tant que service Windows, qui continuera à fonctionner sur mon propre minuteur programmé personnalisé.
Les services Windows, dans mon esprit, sont généralement utilisés pour gérer d'autres applications, plutôt que d'être une application de longue durée. OR .. ils exécutent des applications lourdes telles que SQL Server, BizTalk, Connexions RPC, IIS (même si IIS délègue techniquement le travail à 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 rechange ne sont pas disponibles).
Pour un projet, j'ai été impliqué dans le développement de 8 ou 9 services Windows, 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 immédiatement la mémoire.
Le mot 'serv'ice partage 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 périphérique et que j'appelle un service, celui-ci est en cours d'exécution et j'attends une réponse. Si je (os, app, dev) doit simplement exécuter une tâche isolée, je vais exécuter une tâche, mais si je compte communiquer, éventuellement une communication à double sens, je souhaite un service. Cela concerne le moyen le plus efficace de communiquer entre deux choses, ou une seule chose qui veut exécuter une seule tâche.
Ensuite, il y a l'aspect de la planification. Si vous souhaitez que quelque chose soit exécuté à une heure précise, planifiez-le. Si vous ne savez pas quand vous en aurez besoin, ou si vous en avez besoin "à la volée", faites le service.
Ma réponse est de nature plus philosophique parce que cela ressemble beaucoup à la façon dont les humains interagissent et travaillent avec les autres. Plus nous comprenons l'art de la communication et plus les "entités" comprennent leur rôle, plus cette décision devient facile.
Toute la philosophie à part, quand vous "prototypez rapidement", comme le fait souvent mon service informatique, vous faites tout ce que vous devez pour joindre les deux bouts. Une fois que le prototypage et la preuve de concept sont terminé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.
Aucun service Windows n'a besoin d'être connecté, et Windows dispose de fonctionnalités permettant d'arrêter, de démarrer et de consigner les résultats du service.
Une tâche planifiée ne nécessite pas que vous appreniez à écrire un service Windows.
Pourquoi ne pas fournir les deux?
Dans le passé, j’ai mis les éléments de base dans une bibliothèque et encapsulé un appel à Whatever.GoGoGo () à la fois dans un service et dans une application de console.
Avec quelque chose que vous déclenchez toutes les deux minutes, les chances sont décentes de ne pas faire grand-chose (par exemple, une fonction de type "ping"). Les wrappers ne devraient pas contenir plus qu'un simple appel de méthode et une certaine journalisation.
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 sournois de passer d’une approche à l’autre.
Dans le passé, nous utilisions plus ou moins toujours les services Windows, mais de plus en plus de nos clients basculent progressivement vers Azure et il est beaucoup plus simple de passer d’une application console (déployée en tant que tâche planifiée) à une tâche Web dans Azure. Windows, nous nous concentrons sur les tâches planifiées pour le moment. Si nous rencontrons des limitations, nous allons simplement lancer le projet de service Windows et appeler la même logique à partir de là (tant que les clients travaillent sur OnPrem ..) :)
BR, y
Les services Windows veulent plus de patience jusqu'à ce que ce soit fait. Il a un peu difficile le débogage et l’installation. C'est sans visage… Si vous avez besoin d'une tâche qui doit être effectuée toutes les secondes, toutes les minutes ou toutes les heures, choisissez le service Windows.
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 cette tâche.