IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Service windows exécutant une tâche périodique


Sujet :

C#

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 200
    Points : 89
    Points
    89
    Par défaut Service windows exécutant une tâche périodique
    Bonjour,
    Je souhaite développer un sercice windows qui viens périodiquement (toutes les 10s) effectuer une tache (scruter si un lecteur usb est présent).

    Quelqu'un aurait une trame pour la structure d'une telle application ?

    Concretement, que mettre dans l'évènement "OnStart" ? "OnStop" ?
    Faut-il passer par un thread indépendant ou est-ce inutile ?

    Merci d'avance

    Nicolas
    Strasbourg

  2. #2
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    OnStart démarre un timer (System.Threading.Timer)
    OnStop Arrête un timer

    Dans le callback du timer, tu fais tes traitements.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 200
    Points : 89
    Points
    89
    Par défaut
    Citation Envoyé par SaumonAgile Voir le message
    OnStop Arrête un timer.
    Rien d'autre à faire ? détruire le timer ?

  4. #4
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Points : 6 334
    Points
    6 334
    Par défaut
    Tout simplement : défaire ce qui est fait dans le OnStart.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  5. #5
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Points : 4 061
    Points
    4 061
    Par défaut
    Plus généralement :
    OnStart s'exécute au démarrage du service et OnStop à son arrêt.

    Ensuite ce forum contient déjà pas mal de sujet traitant ces choses là ...
    Pourquoi faire compliqué lorsque l'on peut faire encore plus compliqué.

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 103
    Points : 1 561
    Points
    1 561
    Par défaut
    Attention à bien utiliser System.Timers.Timer plutôt que System.Threading.Timer ou pire le timer des winforms.

    il y a plusieurs raisons à ce choix... System.Timers.Timer est précis sur l'interval que tu donne.
    System.Threading.Timer utilise la synchro sur thread, cela se fait donc sur un nombre "évalué" de quantums, et laisse un peu libre l'ordonnanceur de faire ce qu'il veut.
    En moyenne un timer sur 10s peut se lancer au bout de 7s avec un Systm.Threading.Timer... mais il peut aussi se lancer au bout de 12s... J'ai même vu un interval de soit disant 1mn durer 13s... Peut mieux faire question précision.

    Il ne faut faire appel à des Composants des Winforms. Tout ce qui se situe ou fait appel au System.Forms est à proscrire, exception faite de quelques composants spécifiquement prévus, comme EventLog. Les autres composants ne fonctionnent pas dans un service windows car il n'y a pas de file et de queue de message windows.
    Nota : Windows n'alloue pas de queue de messages windows à des process services excepté ceux ayant recut le flag "peut interagir avec la session". Donc l'utilisation de Application ne sert à rien... puisque le process principal essaiera de pomper un message qui ne viendra jamais.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2008
    Messages : 58
    Points : 74
    Points
    74
    Par défaut
    Si tu essaies de détecter un lecteur USB, j'avais répondu à un post sur un autre forum dans lequel était cité ce code que j'avais corrigé. Ca eviterait d'utiliser un timer inutilement et de travailler en quasi-temps réel.

    Voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
     // This code demonstrates how to monitor the 'Win32_DiskDrive' for
    // the arrival of creation/operation events
    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.Management;
    class WMIEvent
    {
        public static void Main()
        {
            WMIEvent we = new WMIEvent();
            ManagementEventWatcher w = null;
            WqlEventQuery q;
            ManagementOperationObserver observer = new
    ManagementOperationObserver();
            // Bind to local machine
            ManagementScope scope = new ManagementScope("root\\CIMV2");
            scope.Options.EnablePrivileges = true; //sets required
    privilege
            try
            {
     
                q = new WqlEventQuery();
                q.EventClassName = "__InstanceOperationEvent";
                q.WithinInterval = new TimeSpan(0, 0, 3);
                q.Condition = @"TargetInstance ISA 'Win32_DiskDrive' ";
     
                //Console.WriteLine(q.QueryString);
                w = new ManagementEventWatcher(q);
     
                w.EventArrived += new
    EventArrivedEventHandler(we.UsbEventArrived);
                w.Start();
                Console.ReadLine(); // block main thread for test
    purposes
     
            }
     
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
     
            }
     
            finally
            {
                w.Stop();
     
            }
        }
     
        public void UsbEventArrived(object sender, EventArrivedEventArgs
    e)
        {
     
                ManagementBaseObject mbo = null;
     
                mbo = (ManagementBaseObject)e.NewEvent;
            if ((mbo.ClassPath.ClassName == "__InstanceCreationEvent"))
                    {
                        Console.WriteLine("Usb inserted");
     
                    }
                    else
                    {
                        Console.WriteLine("Usb removed");
     
                    }
                    Console.WriteLine((string)mbo["Name"]);
     
                    foreach (PropertyData prop in mbo.Properties)
                        Console.WriteLine("{0} - {1}", prop.Name,
    prop.Value);
     
    Console.WriteLine("-----------------------------------");
     
            Console.WriteLine("******************************");
        }

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 103
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 103
    Points : 1 561
    Points
    1 561
    Par défaut
    varod ta solution ne correspond pas au cahier des charges... s'il souhaite un service, je suppose donc qu'il y a une bonne raison... ton application en "temps réel" est une appli console, radicalement différente en terme de mentalité et de fonctionnement.

    Cependant ton code est réutilisable dans un timer d'un service, après quelques manipulations.

    Les raisons pour qu'il veuille un service plutot qu'une appli qu'il lance manuellemnt peuvent être multiple... ne l'ayant pas précisé... il est un peu cavalier de dire ca t'évite d'utiliser un timer...

    De plus dans un service il est INTERDIT de mettre du code "blocant" qui attend on ne sais quoi dans le code du délégué OnStart... En effet, temps que ce délégué ne rend pas le controle le service n'est pas considéré comme lancé par windows... et il peut se faire kill pour avoir été accusé de planter.
    Il faut soit passé par un timer, soit un thread.

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Le code de varod est tout a fait réutilisable dans un service, avec quelques adaptations bien sûr (pas de Console.ReadLine par exemple...)
    Après c'est à Nico_stras de voir si ça lui convient d'utiliser un évènement WMI plutôt qu'un timer, mais à mon avis c'est plus propre.

  10. #10
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Points : 4 061
    Points
    4 061
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Le code de varod est tout a fait réutilisable dans un service, avec quelques adaptations bien sûr (pas de Console.ReadLine par exemple...)
    Après c'est à Nico_stras de voir si ça lui convient d'utiliser un évènement WMI plutôt qu'un timer, mais à mon avis c'est plus propre.
    Pas forcement.
    Par exemple sur un Win XP compact pour terminal mobile, toutes les classes WMI ne sont pas forcément présentes (pareil pour les différentes versions de windows). Certaine sont absente.
    Donc utiliser WMI peut rendre très dépendant le soft du système d'exploitation alors qu'à la base il est dépendant uniquement du framework.
    Déjà que l'utilisation de service rend le code totalement dépendant de windows ...

    Donc on ne peut pas lancer de généralité comme cela surtout que l'auteur n'a pas dit la finalité du projet.

    Et puis le timer c'est très bien. On peut aussi utiliser le tic horloge du système, mais je ne sais pas comment on catch cela.
    Pourquoi faire compliqué lorsque l'on peut faire encore plus compliqué.

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2008
    Messages : 58
    Points : 74
    Points
    74
    Par défaut
    Méa culpa!

    Je voulais juste donner un tit coup de pouce mais surtout pas dire c'est comme ca qu'il faut faire ... Je me doute bien que cela dépend du cahier des charges.

    Par contre, cinemania, je ne suis pas du tout d'accord avec ce que tu dit. Le code est réutilisable pour un service ... certes l'exemple est une application console mais le tout est géré via un évènement ... tout comme le fait un timer.

    Cependant, selon le périmètre en terme d'OS ... il est clair qu'avant d'utiliser ce code, il est nécessaire de vérifier que ca fonctionne bien (ce doit être cependant compatible XP, 2003 et Vista). Enfin bon, je ne sais pas si ca arrive régulièrement de penser à la compatibilité d'un service sur windows xp compact lors d'un développement. Pour avoir fait des dév. sur .NET CF 2.0, c'est sûr que l'on ne développe pas du tout de la mm facon.

    Vince.

  12. #12
    Expert confirmé
    Avatar de ced600
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2006
    Messages
    3 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Août 2006
    Messages : 3 364
    Points : 4 061
    Points
    4 061
    Par défaut
    Aucun problème cela reste un bon exemple de comment on peut utiliser WMI en C#.

    Vu que tu as l'air de connaitre un peu les objets WMI qui gère les disques, tu utiliserais quel objet pour changer la lettre d'un lecteur (tous type de lecteur).
    J'ai essaye avec du logicaldisk, usbdrive, CDROmdrive, ... mais la modification des propriétés n'est prise en compte que pour une seconde.
    Désolé de cette apparté c pour résoudre le problème de quelqu'un dans le fofo VBS.

    Et pour finir -> les timers c'est bien parce que je le dit, et que dieu dit toujours la vérité
    Pourquoi faire compliqué lorsque l'on peut faire encore plus compliqué.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations forums :
    Inscription : Mars 2008
    Messages : 58
    Points : 74
    Points
    74
    Par défaut
    Citation Envoyé par ced600 Voir le message
    Aucun problème cela reste un bon exemple de comment on peut utiliser WMI en C#.

    Vu que tu as l'air de connaitre un peu les objets WMI qui gère les disques, tu utiliserais quel objet pour changer la lettre d'un lecteur (tous type de lecteur).
    J'ai essaye avec du logicaldisk, usbdrive, CDROmdrive, ... mais la modification des propriétés n'est prise en compte que pour une seconde.
    Désolé de cette apparté c pour résoudre le problème de quelqu'un dans le fofo VBS.

    Et pour finir -> les timers c'est bien parce que je le dit, et que dieu dit toujours la vérité
    Malheureusement, je ne connais pas plus que ça ... je vais jeter un oeil et je te tiens au courant.

    Vince.

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    200
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 200
    Points : 89
    Points
    89
    Par défaut
    Un grand merci à tous pour ces infos

    J'ai au final utilisé l'objet System.Timers.Timer

    Quant à l'application, il s'agit de venir lire un paramètre du périphérique USB connecté.
    Pour se faire, j'ai une API .Net du fabriquant, donc pas de soucis.

    Encore merci...

    Nicolas
    Strasbourg

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Installation d'un service Windows dans une tâche de démarrage
    Par ybrunet dans le forum Microsoft Azure
    Réponses: 1
    Dernier message: 03/01/2012, 16h15
  2. Exécuter une tâche à heure précise ?
    Par [ZiP] dans le forum Débuter
    Réponses: 7
    Dernier message: 24/11/2008, 15h07
  3. Exécution une reqête périodiquement
    Par guy_antoine_mav dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 29/08/2008, 18h08
  4. Gérer un service windows depuis une page ASPX
    Par Patoche34 dans le forum ASP.NET
    Réponses: 3
    Dernier message: 25/06/2008, 17h46
  5. Exécuter une tâche planifiée avec cron
    Par Olivier Regnier dans le forum Administration système
    Réponses: 6
    Dernier message: 30/03/2007, 22h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo