web-dev-qa-db-fra.com

Meilleur moyen d'exécuter des tâches planifiées

Aujourd'hui, nous avons créé une application console pour exécuter les tâches planifiées pour notre site Web ASP.NET. Mais je pense que cette approche est un peu sujette aux erreurs et difficile à maintenir. Comment exécutez-vous votre tâche planifiée (dans un environnement Windows/IIS/ASP.NET)

Mise à jour:

Exemples de tâches:

  • Envoi de courrier électronique à partir d'une file d'attente de courrier électronique dans la base de données
  • Supprimer des objets obsolètes de la base de données
  • Récupérer les statistiques de Google AdWords et remplir un tableau dans la base de données.
223
Niels Bosma

Toutes mes tâches (qui doivent être planifiées) pour un site Web sont conservées dans le site Web et appelées à partir d'une page spéciale. J'ai ensuite écrit un simple service Windows qui appelle cette page de temps en temps. Une fois que la page est exécutée, elle renvoie une valeur. Si je sais qu'il reste encore du travail à faire, je lance la page à nouveau tout de suite, sinon je la lance dans quelques instants. Cela a très bien fonctionné pour moi et conserve toute ma logique de tâche avec le code Web. Avant d'écrire le simple service Windows, j'utilisais le planificateur Windows pour appeler la page toutes les x minutes.

Une autre méthode pratique consiste à utiliser un service de surveillance tel que Pingdom . Pointez leur contrôle http vers la page qui exécute votre code de service. Demandez à la page de renvoyer des résultats qui peuvent ensuite être utilisés pour que Pingdom envoie des messages d’alerte lorsque quelque chose ne va pas.

71
Brettski

Cette technique de Jeff Atwood pour Stackoverflow est la méthode la plus simple que j'ai rencontrée. Il repose sur le mécanisme de rappel "élément de cache supprimé" intégré au système de cache d'ASP.NET.

Mise à jour: Stackoverflow a dépassé cette méthode. Cela ne fonctionne que lorsque le site Web est en cours d'exécution, mais c'est une technique très simple qui est utile pour beaucoup de gens.

Consultez également Quartz.NET

127
BC.

Créez un service Windows personnalisé .

Certaines tâches critiques ont été configurées en tant qu'applications de console planifiées et je les ai trouvées difficiles à gérer. J'ai créé un service Windows avec un "battement de coeur" qui vérifiait un programme de ma base de données toutes les deux minutes. Cela a très bien fonctionné.

Cela dit, j'utilise toujours des applications de console planifiées pour la plupart de mes tâches de maintenance non critiques. Si ce n'est pas cassé, ne le répare pas.

30
Chris Van Opstal

J'ai trouvé cela facile pour toutes les personnes impliquées:

  • Créer une méthode de service Web telle que DoSuchAndSuchProcess
  • Créez une application console qui appelle cette méthode Web.
  • Planifiez l'application de la console dans le planificateur de tâches.

En utilisant cette méthodologie, toute votre logique métier est contenue dans votre application Web, mais vous disposez de la fiabilité du gestionnaire de tâches Windows ou de tout autre gestionnaire de tâches commercial pour lancer le processus et enregistrer toutes les informations renvoyées, telles qu'un rapport d'exécution. L'utilisation d'un service Web au lieu de la publication sur une page présente un avantage, car il est plus facile d'obtenir les données renvoyées à partir d'un service Web.

17
Daniel Auger

Pourquoi réinventer la roue, utilisez les classes Threading et Timer.

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }
10
Moises Goncalves

Utilisez le planificateur Windows pour exécuter une page Web.

Pour empêcher les utilisateurs malveillants ou les araignées des moteurs de recherche de l'exécuter, lorsque vous configurez la tâche planifiée, appelez simplement la page Web avec une chaîne de requête, par exemple: mypage.aspx? From = schedtask

Ensuite, dans le chargement de la page, utilisez simplement une condition: if (Request.Querystring ["from"] == "schedtask") {// executeetask}

De cette manière, aucun moteur de recherche ni utilisateur malveillant ne pourra exécuter votre tâche planifiée.

8
philberg

Cette bibliothèque fonctionne comme un charme http://www.codeproject.com/KB/cs/tsnewlib.aspx

Il vous permet de gérer les tâches planifiées Windows directement via votre code .NET.

4
labilbe

De plus, si votre application utilise SQL SERVER, vous pouvez utiliser l'agent SQL pour planifier vos tâches. C’est là que nous mettons généralement du code récurrent basé sur les données (rappels par courrier électronique, maintenance planifiée, purges, etc.). Une fonctionnalité intéressante intégrée à l'agent SQL est les options de notification d'échec, qui peuvent vous alerter en cas d'échec d'une tâche critique.

3
Zachary

Je ne sais pas de quel genre de tâches planifiées vous parlez. Si vous voulez parler de tâches du type "chaque heure, actualisez foo.xml", utilisez le système de tâches planifiées de Windows. (La commande "at" ou via le contrôleur.) Demandez-lui d’exécuter une application console ou de demander une page spéciale qui lance le processus.

Edit: je devrais ajouter, c’est un moyen correct d’exécuter votre application IIS à des points planifiés également. Supposons donc que vous souhaitiez vérifier votre base de données toutes les 30 minutes et que des rappels aux utilisateurs soient envoyés par courrier électronique à propos de certaines données. Vous pouvez utiliser des tâches planifiées pour demander cette page et obtenir ainsi le traitement de IIS.

Si vos besoins sont plus complexes, vous pouvez envisager de créer un service Windows et de le laisser exécuter une boucle pour effectuer le traitement dont vous avez besoin. Cela présente également l'avantage de séparer le code à des fins de dimensionnement ou de gestion. En revanche, vous devez traiter avec les services Windows.

2
MichaelGG

Si vous possédez le serveur, vous devez utiliser le planificateur de tâches Windows. Utilisez AT /? à partir de la ligne de commande pour voir les options.

Sinon, à partir d'un environnement Web, vous devrez peut-être faire quelque chose de désagréable, comme configurer un autre ordinateur pour envoyer des requêtes à une page donnée selon un intervalle de temps défini.

2
t3rse

J'ai utilisé Abidar avec succès dans un projet ASP.NET (en voici quelques-uns informations générales ).

Le seul problème avec cette méthode est que les tâches ne s'exécutent pas si l'application Web ASP.NET est déchargée de la mémoire (c'est-à-dire en raison d'une faible utilisation). Une chose que j’ai essayée, c’est de créer une tâche pour accéder à l’application Web toutes les 5 minutes et de la maintenir en vie, mais cela ne semble pas fonctionner de manière fiable. C’est pourquoi je me sers du planificateur Windows et de l’application de base pour la console.

La solution idéale consiste à créer un service Windows, bien que cela puisse ne pas être possible (c'est-à-dire si vous utilisez un environnement d'hébergement partagé). Cela facilite également les choses du point de vue de la maintenance pour conserver les choses dans l'application Web.

2
Mun

Voici un autre moyen:

1) Créez un script Web "heartbeat" responsable du lancement des tâches, si elles sont DUE ou en retard.

2) Créez un processus planifié quelque part (de préférence sur le même serveur Web) qui atteint le script Web et le force à s'exécuter à un intervalle régulier. (par exemple, une tâche de planification Windows qui lance silencieusement le script Heatbeat en utilisant IE ou whathaveyou)

Le fait que le code de la tâche soit contenu dans un script Web est uniquement destiné à conserver le code à l'intérieur de la base de code de l'application Web (l'hypothèse étant que les deux dépendent l'un de l'autre), ce qui être plus facile à gérer pour les développeurs Web.

L'approche alternative consiste à créer un script/programme de serveur exécutable qui exécute tout le travail de planification et à exécuter l'exécutable lui-même en tant que tâche planifiée. Cela peut permettre un découplage fondamental entre l'application Web et la tâche planifiée. Par conséquent, si vous avez besoin que vos tâches planifiées soient exécutées même lorsque l'application/la base de données Web est peut-être en panne ou inaccessible, vous devriez opter pour cette approche.

1
Matias Nino

Vous pouvez facilement créer un service Windows qui exécute le code sur intervalle à l'aide de la méthode 'ThreadPool.RegisterWaitForSingleObject'. C'est vraiment facile et assez facile à mettre en place. Cette méthode est une approche plus rationnelle que l’utilisation des timers dans le cadre.

Consultez le lien ci-dessous pour plus d'informations:

Exécution d'un processus périodique dans .NET à l'aide d'un service Windows:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

1
atconway

Nous utilisons également des applications console. Si vous utilisez des outils de journalisation tels que Log4net, vous pouvez surveiller correctement leur exécution. De plus, je ne vois pas en quoi elles sont plus difficiles à gérer qu'une page Web, étant donné que vous partagez peut-être certaines des mêmes bibliothèques de code entre les deux si elles sont conçues correctement.

Si vous ne souhaitez pas que ces tâches soient exécutées à une heure précise, vous pouvez avoir une page Web dans votre section administrative de votre site Web qui fait office de file d'attente. L'utilisateur introduit une requête pour exécuter la tâche. Il insère à son tour un enregistrement d'horodatage vierge dans la table MyProcessQueue et votre tâche planifiée vérifie toutes les X minutes la présence d'un nouvel enregistrement dans MyProcessQueue. De cette façon, il ne fonctionne que lorsque le client le souhaite.

J'espère que ces suggestions vous aideront.

0
Kyle Ballard

Une option serait de configurer un service Windows et de le faire appeler votre tâche planifiée.

Dans les formats que j'ai utilisés, les timers ne pensent pas que cela fonctionnerait bien dans ASP.NET

0
AJM