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 Optimisation


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2007
    Messages
    497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 497
    Par défaut Service Windows Optimisation
    Bonjour,

    Je viens de creer mon premier service qui fonctionne
    Bon et comme c'est mon premier service je suppose qu'il est tout pourri

    Aussi je le pose ici en esperant que deux trois âmes charitables a l'esprit eclaire serait disponible pour me dire ce qui est bon ou pas bon dans mon code. Comment l'ameliorer, optimiser etc...

    Bon n'hesitez pas a critiquer, insulter, vous moquer .. tant que ca reste constructif


    Deja il y a un truc bizarre. Normalment j'ai programme pour demande que mon service envoie un sms toutes les 2 sec. Dans les faits j'ai l'impression qu'il envoie 2 ou 3 sms toutes les secondes
    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.ServiceProcess;
    using System.Text;
    using System.Net;
    using System.IO;
    using Npgsql;
    using System.Timers;
     
     
    namespace ServiceLudendo
    {
        public partial class Service1 : ServiceBase
        {
            public Service1()
            {
                InitializeComponent();
            }
     
            protected override void OnStart(string[] args)
            {
                System.Diagnostics.EventLog.WriteEntry("Arnaud ", "test Service démaré");
     
     
                System.Timers.Timer aTimer = new System.Timers.Timer();
     
                aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
     
                // Set the Interval to 2 seconds (2000 milliseconds).
                aTimer.Interval = 2000;
                aTimer.Enabled = true;
     
                // Keep the timer alive until the end of Main.
                GC.KeepAlive(aTimer);
            }
     
            // Specify what you want to happen when the Elapsed event is 
            // raised.
            private void OnTimedEvent(object source, ElapsedEventArgs e)
            {
                EnvoieSMS();
                RecupDonnee();
            }
     
     
     
            /// <summary>
            /// Stop this service.
            /// </summary>
            protected override void OnStop()
            {
                System.Diagnostics.EventLog.WriteEntry("Arnaud ", "test Service arrete");
            }
     
            /// <summary>
            /// Envoie d'un SMS... Par la suite le numero de portable a joindre sera recupere dans la bdd.
            /// </summary>
            private void EnvoieSMS()
            {
                string url = "http://www.msinnovations.com/smsmod/amsmodule.sendsms.v2.php?clientcode=*******&passcode=******&XMLFlow=<DATA><CLIENT>********</CLIENT><MESSAGE>"
               + DateTime.Now.ToString()
               + " "
               + "DEPUIS UN SERVICE "
               + "</MESSAGE>"
               + "<CAMPAIGN_NAME>****</CAMPAIGN_NAME>"
               + "<MOBILEPHONE>*******</MOBILEPHONE></DATA>";
     
                HttpWebResponse HttpWResponse;
                HttpWebRequest HttpWReq;
                StreamReader sr = null;
     
                try
                {
                    HttpWReq = (HttpWebRequest)WebRequest.Create(url);
     
                    HttpWReq.Method = "GET";
                    HttpWReq.KeepAlive = true;
                    HttpWReq.UserAgent = "CodaSystem";
                    HttpWResponse = (HttpWebResponse)HttpWReq.GetResponse();
     
                    sr = new StreamReader(HttpWResponse.GetResponseStream());
     
                    System.Diagnostics.EventLog.WriteEntry("Arnaud ", "SR Envoie reussi " + sr.ReadToEnd() + "");
     
                }
                catch
                {
                    System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme dans l'envoie SMS");
                }
                finally
                {
                    sr.Close();
                    HttpWReq = null;
                    HttpWResponse = null;
                }
            }
     
            /// <summary>
            /// Recuperation de donnee dans la BDD. Ici je recupere des donnees bidon c'est juste pour verifier que ca marche. Par la suite en fonction de ces donnees j'enverrais ou non le SMS.
            /// </summary>
            protected void RecupDonnee()
            {
     
                NpgsqlConnection connexion = new NpgsqlConnection("Server=******.com;Port=****;User Id=*****;Password=*****;Database=*****;ssl=true");
                NpgsqlCommand command = null;
                NpgsqlDataReader dr = null;
     
                try
                {
     
                    connexion.Open();
     
                    string requete = "SELECT * FROM equipes WHERE idequipe = 1 LIMIT 1";
                    command = new NpgsqlCommand(requete, connexion);
     
                    dr = command.ExecuteReader();
     
                    dr.Read();
     
                    string nom = "";
                    if (!(dr.IsDBNull(1))) { nom = (string)dr[1]; }
     
                    System.Diagnostics.EventLog.WriteEntry("Arnaud ", "On recupere ca dans la bdd " + nom);
     
     
     
                }
                catch (Exception ex)
                {
                    System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme avec postgresql" + ex.ToString());
                }
                finally
                {
                    command = null;
                    dr.Close();
                    dr = null;
                    connexion.Close();
                    connexion = null;
                }
             }
     
     
        }
     
     
    }

    D avance merci

  2. #2
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Salut,

    pour le cote service, personnellement, je n'en ai plus fait depuis...euh...longtemps

    Niveau critiques, ce sera donc pas sur le service

    Par contre...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
      EnvoieSMS();
      RecupDonnee();
    }
    Pour moi, RecupDonnee doit etre dans EnvoieSMS ...sinon, pas logique

    Essaye de remplacer les blocs de style:

    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
     
    HttpWebResponse HttpWResponse;
    HttpWebRequest HttpWReq;
    StreamReader sr = null;
     
    try
    {
                    HttpWReq = (HttpWebRequest)WebRequest.Create(url);
                    HttpWResponse = (HttpWebResponse)HttpWReq.GetResponse();
                     sr = new StreamReader(HttpWResponse.GetResponseStream());
     
                }
                catch
                {
                    System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme dans l'envoie SMS");
                }
                finally
                {
                    sr.Close();
                    HttpWReq = null;
                    HttpWResponse = null;
                }
    Par du:
    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
     
     
    try{
     
      HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;  
     
      if (request == null) {
        System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme dans l'envoie SMS");
      }
     
      using(HttpWebResponse HttpWResponse = (HttpWebResponse)request .GetResponse()){
          using(StreamReader sr = new StreamReader(HttpWResponse.GetResponseStream()){
         ...
          }
        }
      }catch{
      System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme dans l'envoie SMS");
    }
    Apres, ca serait bien, pour des raisons de maintenance, de deporter la logique de log dans une autre classe / fonction, parce que loger dans le'eventlog, c'est pas mal pendant le dev, mais tu risques d'eter amene a changer ton systeme de log avant la mise en prod

    le bout de code suivant aussi, d'ailleurs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    string url = "http://www.msinnovations.com/smsmod/amsmodule.sendsms.v2.php?clientcode=*******&passcode=******&XMLFlow=<DATA><CLIENT>********</CLIENT><MESSAGE>"
               + DateTime.Now.ToString()
               + " "
               + "DEPUIS UN SERVICE "
               + "</MESSAGE>"
               + "<CAMPAIGN_NAME>Ludendo</CAMPAIGN_NAME>"
               + "<MOBILEPHONE>*******</MOBILEPHONE></DATA>";
    Genre, dans une fonction GenererMessage(url, client, message, campaign, mobilephone), ou dans une classe MessageGenerator

    Apres, pareil, pour la partie acces aux donnees, utiliser des using + deporter les parties communes


    Mais c'est parce que je suis maniaque

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  3. #3
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    C'est du code qui fonctionne mais sans plus....

    1) C'est quoi cet appel à GC.KeepAlive? Tu sais que les cas ou l'on doit appeler les méthodes du GC ne sont pas monnaie courante et restent souvent des solutions de derniers recours. En l'occurence un keepalive c'est mauvais.

    Tu perds complètement la main sur l'objet parce que t'as plus de référence dessus. Pourquoi ne pas déclarer ce Timer comme membre de la classe et l'arrêter proprement dans OnStop?

    2) Ta méthode EnvoieSms fait trop de choses, formater l'URL et faire la requête c'est deux choses différentes.

    3) Ta manie de mettre à null les variables locales est quelque chose d'inutile à supprimer, je te conseille de lire un article sur la portée des variables.

    4) On ne met jamais de catch(Exception ) dans un code parce que ça supprime n'importe quoi, y compris les erreurs gravissimes concernant le framework ou la mémoire. Si tu veux faire un catch(Exception), tu dois obligatoirement avoir un throw; pour propager l'exception.

    5) Ta clause finally est mal écrite, tu fais un dr.Close(); si la connexion a la base de donnée a échoué, dr vaut null et c'est un NullPointerException garanti. Meme chose, si connexion.Open(); a échoué, suivant l'implémentation de *Close*, tu vas te ramasser un InvalidOperation ou un truc dans le genre, vérifie que la connexion est ouverte avant d'essayer de la fermer!

    6) if (!(dr.IsDBNull(1))) { nom = (string)dr[1]; }, t'as pensé à ce que ça ferait si ton Select retournait aucune ligne? Teste au moins la valeur de retour de DataReader.Read pour éviter une bonne grosse exception.

    7) string requete = "SELECT * FROM equipes WHERE idequipe = 1 LIMIT 1";
    ça c'est une requête à la noix parce que tu as AUCUNE idée de l'ordre dans lequel les colonnes vont être retournées, ni leur nombre. Donc un Select * c'est à bannir!!! Tu spécifies toujours les colonnes, dans ce cas c'est un "Select Nom FROM Equipes....." que tu feras, et tu peux utiliser ExecuteScalar puisque tu as besoin que d'une seule valeur.
    Par ailleurs, LIMIT 1 c'est risible dans le cas ou idequipe est la clef primaire de la table equipes.

    8) Les objets de base de données proposent une méthodes Dispose, il faut l'appeler dans les finally, ou utiliser des clauses Using.


    Voilà déjà de quoi t'occuper un moment.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2007
    Messages
    497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 497
    Par défaut
    Tout d'abord merci a vous deux pour vos commentaires.

    J'ai de nouvelles questions par rapport a ce programme.
    1. Sous linux quand on cree un deamon il est conseille de l'arreter de temps en temps (exemple quand il tourne depuis plus d'une semaine) et de laisser linux le relancer automatiquement. Peut on faire de meme sous windows?

    2. Mon programme doit bien se delcencher toutes les deux secondes? Est ce qu'une impression si il se declenche plus souvent ou ai je fait une fausse manip?

    3.Sinon mon abonnement appelant OnTimedEvent se trouve dans le onstart. Est ce le bon endroit pour m'inscrire a cet abonnement?



    Citation Envoyé par pvialatte Voir le message
    pour le cote service, personnellement, je n'en ai plus fait depuis...euh...longtemps
    Euh? ca veut dire que ce que je souhaite faire ici:
    Realiser une application qui regulierement (ex tout les 15 min) va verifier differentes donnees dans une BDD et en fonction reagir (ex envoyer ou non un SMS).
    Peut etre fait autrement? Il n'est pas utile de faire un service pour ca?

    Citation Envoyé par pvialatte Voir le message
    Pour moi, RecupDonnee doit etre dans EnvoieSMS ...sinon, pas logique
    Yes tout a fait d'accord quand je l'ai fait je testais differentes chose d'ou cet aspect du code


    Citation Envoyé par pvialatte Voir le message
    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
     
    try{
     
      HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;  
     
      if (request == null) {
        System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme dans l'envoie SMS");
      }
     
      using(HttpWebResponse HttpWResponse = (HttpWebResponse)request .GetResponse()){
          using(StreamReader sr = new StreamReader(HttpWResponse.GetResponseStream()){
         ...
          }
        }
      }catch{
      System.Diagnostics.EventLog.WriteEntry("Arnaud ", "Probleme dans l'envoie SMS");
    }
    Pourquoi
    HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
    est mieux que
    HttpWReq = (HttpWebRequest)WebRequest.Create(url);
    Est ce que c'est parce que ca evite de passer par un cast?

    Pour le using. Je comprend pas ce que tu as ecrit... :s A quoi il sert la?

    Sinon pour le reste (création de fonctions etc) je suis tout a fait d'accord, merci.

    Citation Envoyé par _skip Voir le message

    1) C'est quoi cet appel à GC.KeepAlive? Tu sais que les cas ou l'on doit appeler les méthodes du GC ne sont pas monnaie courante et restent souvent des solutions de derniers recours. En l'occurence un keepalive c'est mauvais.

    Tu perds complètement la main sur l'objet parce que t'as plus de référence dessus. Pourquoi ne pas déclarer ce Timer comme membre de la classe et l'arrêter proprement dans OnStop?
    En fait ca provient de la doc ms vs 2005 (cf ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.NETDEVFX.v20.fr/cpref12/html/C_System_Timers_Timer_ctor.htm
    ).
    Je vais essayer de faire ce que tu as dit.

    Citation Envoyé par _skip Voir le message
    2) Ta méthode EnvoieSms fait trop de choses, formater l'URL et faire la requête c'est deux choses différentes.
    Oui.

    Citation Envoyé par _skip Voir le message
    3) Ta manie de mettre à null les variables locales est quelque chose d'inutile à supprimer, je te conseille de lire un article sur la portée des variables.
    Justement je sors d'un cours ou on nous appris a mettre nos objets a null pour que le garbage collector puisse récupérer la mémoire occupée.



    Citation Envoyé par _skip Voir le message
    4) On ne met jamais de catch(Exception ) dans un code parce que ça supprime n'importe quoi, y compris les erreurs gravissimes concernant le framework ou la mémoire. Si tu veux faire un catch(Exception), tu dois obligatoirement avoir un throw; pour propager l'exception.
    Oui.

    Citation Envoyé par _skip Voir le message
    5) Ta clause finally est mal écrite, tu fais un dr.Close(); si la connexion a la base de donnée a échoué, dr vaut null et c'est un NullPointerException garanti. Meme chose, si connexion.Open(); a échoué, suivant l'implémentation de *Close*, tu vas te ramasser un InvalidOperation ou un truc dans le genre, vérifie que la connexion est ouverte avant d'essayer de la fermer!
    Ok je savais pas. Je pensais que ca verifiait si c'etait ouvert avant de fermer.
    D'ailleurs je viens de verifier pour
    NpgsqlConnection connexion
    et NpgsqlDataReader dr

    tenter de les fermer alors qu'ils ne sont pas ouvert ne provoque pas d'exception.
    (par contre pour un streamreader ca provoque une exception)

    Citation Envoyé par _skip Voir le message
    6) if (!(dr.IsDBNull(1))) { nom = (string)dr[1]; }, t'as pensé à ce que ça ferait si ton Select retournait aucune ligne? Teste au moins la valeur de retour de DataReader.Read pour éviter une bonne grosse exception.
    Bien vu je corrige ca.

    Citation Envoyé par _skip Voir le message
    7) string requete = "SELECT * FROM equipes WHERE idequipe = 1 LIMIT 1";
    ça c'est une requête à la noix parce que tu as AUCUNE idée de l'ordre dans lequel les colonnes vont être retournées, ni leur nombre. Donc un Select * c'est à bannir!!! Tu spécifies toujours les colonnes, dans ce cas c'est un "Select Nom FROM Equipes....." que tu feras, et tu peux utiliser ExecuteScalar puisque tu as besoin que d'une seule valeur.
    Par ailleurs, LIMIT 1 c'est risible dans le cas ou idequipe est la clef primaire de la table equipes.
    EUh oui c'etait une versiond e test que j'ai developpe donc j'ai mis une requete bidon donc j'etais sur qu'elle me renverrait quelque chose. D'habitude j utilise pas de select *
    Pour le limit 1 perso je trouve pas ca risible vu ce que je me souviens de mes cours puisque ca permet a la bdd de s'arreter des qu'elle a trouve un champs et on m' a toujours dis de le mettre meme sur une clef primaire. Apres tout meme ci c'est inutile ca peut pas faire de mal...
    Pour le executescalar j'en prends bonne note.


    Citation Envoyé par _skip Voir le message
    8) Les objets de base de données proposent une méthodes Dispose, il faut l'appeler dans les finally, ou utiliser des clauses Using.
    Mettre a null pour moi revenait a apeller dispose...
    Pas compris pour les clauses using.

    Citation Envoyé par _skip Voir le message
    Voilà déjà de quoi t'occuper un moment.
    Bon je vais essayer de nettoyer tout ca.

  5. #5
    Membre éprouvé
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Par défaut
    Pour le limit 1 perso je trouve pas ca risible vu ce que je me souviens de mes cours puisque ca permet a la bdd de s'arreter des qu'elle a trouve un champs et on m' a toujours dis de le mettre meme sur une clef primaire. Apres tout meme ci c'est inutile ca peut pas faire de mal...
    Pour le executescalar j'en prends bonne note.
    Je m'excuse mais celui qui t'as dit ça devait pas savoir ce qu'est une clef primaire et encore moins une recherche d'égalité dans un index.

    Justement je sors d'un cours ou on nous appris a mettre nos objets a null pour que le garbage collector puisse récupérer la mémoire occupée.
    Ce n'est pas le fait que tu mettes une référence à null qui détermine ça, toutes les variables qui sortent de leur portée deviennent éligibles pour le GC. D'ailleurs quand celui-ci passera, ta méthode aura fini de s'exécuter, depuis longtemps suivant comment.

  6. #6
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Citation Envoyé par xian21 Voir le message
    Pas compris pour les clauses using.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    using(StreamReader sr = new StreamReader(HttpWResponse.GetResponseStream()){
         ...
          }
    est (grosso modo) equivalent, une fois compile, a :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    try{
    StreamReader sr = new StreamReader(HttpWResponse.GetResponseStream());
    .....
    }catch (Exception ex){
      throw ex;
    }finally{
      sr.Dispose();
    }
    C'est une facilite d écriture pour t'assurer que les objets implémentant IDisposable sont bien Disposes

    ......

    Euh? ca veut dire que ce que je souhaite faire ici:
    Realiser une application qui regulierement (ex tout les 15 min) va verifier differentes donnees dans une BDD et en fonction reagir (ex envoyer ou non un SMS).
    Peut etre fait autrement? Il n'est pas utile de faire un service pour ca?
    Ca veut dire que je n'ai pas fait de service windows depuis 2 ans

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 99
    Par défaut
    Bonjour,

    Tu as un problème avec ton timer parce que si le temps d'envoi d'un sms est supérieur à l'intervalle du timer (2 secs), les appels s'empilent et tu enverras tes sms en rafale dès que le tps d'exe sera < intervalle, le temps de dépiler les appels. Tu peux ajouter .enabled = false en entrée et .enabled = true en sortie ce qui fera 1 sms envoyé 2 secs aprés le dernier envoi.

    Si c'est réellement toutes les 2 secs, tu as interêt à gèrer un cache (par exemple recuperer les n prochaines équipes, je ne pense pas que ces infos soient volatiles).

    Remplace le 'SELECT *...' par 'SELECT {seulement les champs qui t'intéressent}'

    Pascal

Discussions similaires

  1. [WinService][C#] Comment déployer un service windows ?
    Par sokette dans le forum Windows Forms
    Réponses: 5
    Dernier message: 27/04/2005, 16h38
  2. Planifier le démarrage d'un service Window
    Par tscoops dans le forum Windows XP
    Réponses: 2
    Dernier message: 29/03/2005, 14h56
  3. [WD7.5] Service Windows
    Par cqfd dans le forum WinDev
    Réponses: 1
    Dernier message: 29/03/2005, 08h58
  4. [VB6]Arreter un service windows
    Par bouboussjunior dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 04/10/2004, 17h03
  5. [C#] Icône, barre des tâches et Service Windows
    Par SErhio dans le forum Windows Forms
    Réponses: 17
    Dernier message: 03/09/2004, 12h56

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