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 :

timer c# peu précis ?


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Par défaut timer c# peu précis ?
    Salut

    Je sais c'est une question récurrente mais pas trouvé de réponse claire.

    J'ai testé les deux exemples sur MSDN pour
    System.Threading.Timer
    et System.Timers.Timer
    mais lorsque j'essaye d'avoir une précision de 1000 ms par exemple j'ai toujours un décalage de 14 ms en trop (parfois 13).
    j'ai pourtant un pc puissant et ces fonctions descendent a priori jusqu'à la milliseconde.
    J'ai aussi jeté un oeil du coté de stopwatch et QueryPerformance mais n'ai pas trouvé comment réaliser un timer qui déclenche une fonction périodiquement, juste des mesures de performances.

    Si quelqu'un a une piste...

  2. #2
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Le problème vient de ce que l'évent du timer n'est pas traité en vrai temps réél.

    On peut amélioer les choses en utilisant un timer avec un tout petit intervalle et de tester ldans l'event le temps écoulé.

    Et, dans tous les cas, le mieux est d'accepter de traiter applicativement des intervalles de taille variable.

  3. #3
    Membre chevronné Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Par défaut
    Salut,

    une fois j'avais un problème similaire, je devais effectuer des actions à des intervalles précis (à la milliseconde près). Le plus précis qu'il soit possible d'obtenir dans un environnement Windows, et ce de manière irréfutable, c'est d'utiliser une référence 'extern' aux librairies système de windows et d'utiliser le chronomètre qui s'y trouve.

    Un exemple ici :
    http://www.codeproject.com/KB/cs/hig...imercshar.aspx

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Par défaut
    Metalgeek, j'ai encore l'impression que ces exemples avec QueryPerformanceCounter et QueryPerformanceFrequency sont surtout utilisés pour du calcul d'exécution, me trompe-je ?

    sinon j'ai trouvé une technique qui semble marcher, je lance un thread avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    System.Threading.Thread monthread = new System.Threading.Thread(methode_timer);
    monthread.Start();
    dans le lequel je boucle et j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.Threading.Thread.Sleep(1);
    La classe System.Threading.Thread offrirait plus de précision que System.Threading.Timer ?

  5. #5
    Membre chevronné Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Par défaut
    j'ai encore l'impression que ces exemples avec QueryPerformanceCounter et QueryPerformanceFrequency sont surtout utilisés pour du calcul d'exécution
    Tu fais une classe static qui exécute une boucle infinie dans un thread de travail, et dans le corps de la boucle tu vérifies combien de temps s'est écoulé. Quand ça correspond à ton intervalle, tu déclenches un évènement.
    Si tu as besoin de plusieurs intervalles différents, tu ne fais pas une classe static mais tu créés un objet pour chaque intervalle. En gros :
    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
     
     
    public delegate void TimerEventHandler(long timeUTC);
     
    public sealed class MonTimer
    {
        private readonly uint _frequency;
        private volatile bool _stopped;
     
        public event TimerEventHandler Tick;
     
        public MonTimer(uint freq)
        {
             this._frequency = freq;
        }
     
       public void Start()
       {
            this._stopped = false;
     
           ThreadPool.QueueUserWorkItem(new WaitCallBack(this.Loop));
       }
     
       public void Stop()
       {
            this._stopped = true;
       }
     
       private void Loop(object stateInfo)
       {
            while (!this._stopped)
            {
                  //Là, tu vérifie avec les fonctions 'extern' si
                  //tu tombes sur l'intervalle qui t'intéresse. Si c'est
                  ///le cas, tu déclenches l'évènement Tick.
            }
       }
    }

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 53
    Par défaut
    juste un truc qui m'a un peu fait galérer,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ThreadPool.QueueUserWorkItem(new WaitCallback(this.Loop));
    WaitCallback c'est avec un b minuscule

    quand tu dis de vérifier les fonctions 'extern', tu parles de QueryPerformanceCounter et frequency ?
    Une boucle qui fait des tests tout le temps ca prend beaucoup de ressource , non ?

    En fait le truc que je cherchais c'est a faire une pause qui puisse être juste un peu en dessous de la milliseconde histoire d'avoir une précision au niveau de la ms assez précise.

    Je viens de trouver que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.Threading.Thread.Sleep();
    avec new TimeSpan() en argument permet de faire beaucoup mieux que la ms

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.Threading.Thread.Sleep(new TimeSpan(10000000));
    ca fait une pause d'une seconde !!

    ensuite j'utilise stopwatch.GetTimestamp() pour vérifier le temps

Discussions similaires

  1. Réponses: 0
    Dernier message: 15/05/2014, 10h30
  2. timer, est-il précis ?
    Par tonnebrre dans le forum VB.NET
    Réponses: 5
    Dernier message: 22/06/2010, 19h50
  3. [Timer]Timer pas très précis
    Par harold63 dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 25/07/2005, 08h36

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