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

VB.NET Discussion :

Outils Timer est il vraiment a la millisecondes


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Novembre 2013
    Messages
    229
    Détails du profil
    Informations forums :
    Inscription : Novembre 2013
    Messages : 229
    Par défaut Outils Timer est il vraiment a la millisecondes
    Bonjour

    Voila je dois lancé une procédure tout les 50 millisecondes mais , il y a qque chose qui me gène avec l'outils timer

    J'a fait un test avec un intervalle de 1000 ms et un variable qui s’incrémente a chaque tick au bout d'une minutes j'obtient bien 60 Tick (60 secondes) , la ca me va.

    Mais si je met un intervalle de 1 ms , je devrait obtenir 60000 Tick alors que je n'obtient que 4399

    SI au lieu d'utiliser une variable genre i = i +1 je prend au démarrage environnemnt.tickCount et pareil a la fin j'obtient bien 60000 Tick

    un peu bizarre , est ce le traitement i = i + 1 qui est si long ??

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Timer1.Start()
    debut =  Environment.TickCount


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            i = i + 1
     
        End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Timer1.Stop()
    fin=  Environment.TickCount
    fin - debut = 60000
    mais i = 4399

    Bon weekend

  2. #2
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Il est bien important de comprendre certaines choses pour comprendre les différences que tu as.

    Tout d'abord, environnemnt.TickCount contient le nombre de millisecondes qui se sont écoulés depuis le démarrage du système. Il ne reflète en aucun cas le nombre de fois où ton timer est appelé.

    La seule méthode pour savoir le nombre d'exécution de ton timer, c'est effectivement d'avoir une variable que tu incrémentes au sein de ton timer.

    Maintenant, les timer en .Net sont imprécis. Préciser qu'un timer se déclenche toutes les 50ms signifie qu'il y aura au moins 50ms entre chaque itération du timer, mais pas qu'il y aura exactement 50ms. Et plus précisément, qu'il y aura au moins 50ms entre la fin d'un timer et le début de l'occurence suivante. Aussi, tu vas avoir un phénomène de dérive qui va s'accumuler au fur et à mesure que le temps passe.

    Pour obtenir ce que tu cherches, à savoir une tâche périodique, il faut que tu détermines toi-même la date de réveil. Voici l'extrait de code d'un article que je suis en train d'écrire sur justement la mise en place de tâche périodique (bon, c'est en C#, mais le principe reste le même)
    Code C# : 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
    private const int PERIOD = 20;
            private static int _occurencesDelayed = 0;
     
     
    static void Main(string[] args)
            {
                CancellationTokenSource cancellationToken = new CancellationTokenSource();
                Thread thread2 = new Thread(periodicTask2);
     
                thread2.Start(cancellationToken.Token);
     
                Console.WriteLine("En attente de la fin des tâches...");
                Thread.Sleep(10000);
                cancellationToken.Cancel();
                thread2.Join();
                Console.WriteLine("Tâches terminées");
                Console.WriteLine("Nombre d'occurrences avec retard : {0}", _occurencesDelayed);
                Console.ReadLine();
            }
     
    public static void periodicTask2(object p)
            {
                CancellationToken cancellationToken = (CancellationToken)p;
                DateTime date = DateTime.Now;
                DateTime startTime = DateTime.Now;
                int count = 0;
                int next;
                while (!cancellationToken.IsCancellationRequested)
                {
                    date = date.AddMilliseconds(PERIOD);
                    TimeSpan delta = DateTime.Now - startTime.AddMilliseconds(count * PERIOD);
     
                    taskBody("1", DateTime.Now, Convert.ToInt32(delta.TotalMilliseconds));
     
                    count++;
                    next = Convert.ToInt32((date - DateTime.Now).TotalMilliseconds);
                    if (next >= 0)
                    {
                        Thread.Sleep(next);
                    }
                    else
                    {
                        _occurencesDelayed ++;
                    }
                }
            }

    taskBody correspond à la méthode qui est appelé à intervalle régulier. Ici, je créé un thread qui va exécuter ma tâche à intervalle régulier. Et avec un peu d'arithmétique, je m'assure qu'il n'y aura pas ce phénomène de dérive des horloges.

    Attention, cela ne veut pas dire que la tâche va s'exécuter exactement toutes les 50ms. Un coup se sera 50ms, un autre coup 52ms, un autre 48ms (si l'occurrence précédente a terminé son exécution "en retard"). Mais l'exécution de la tâche est demandé toutes les 50ms.

    Et si les 50ms sont extrêmement important, tu peux augmenter la priorité de la tâche, afin qu'elle s'exécute prioritairement.

  3. #3
    Membre éclairé
    Inscrit en
    Novembre 2013
    Messages
    229
    Détails du profil
    Informations forums :
    Inscription : Novembre 2013
    Messages : 229
    Par défaut
    Super merci

    Je vais analyser ton code

    Un Grand merci pour ta reponse


    Bon weekend

  4. #4
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour Francois

    Hélas ,d'autres complications sérieuses surgissent ...
    Ainsi si periodicTask2 est un task gourmand en calcul ,il pourrait exiger un temps plus long que celui alloué à chaque itération ....

    En toute rigueur la périodicité allouée est lie à la nature de la tache !!!

  5. #5
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bien sûr ! Mais si la période est inférieure à la durée d'exécution des tâches c'est qu'il y a un défaut de conception à la base !

    La, la question portait sur la fiabilité d'un timer. D'où ma réponse

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/12/2006, 08h39
  2. Unicode est-il vraiment un probleme ?
    Par epsilon68 dans le forum C++
    Réponses: 53
    Dernier message: 04/09/2006, 09h56
  3. Est-ce vraiment légal ?
    Par pi-2r dans le forum Sécurité
    Réponses: 21
    Dernier message: 13/08/2006, 12h17
  4. [Reference][String][Integer] Qu'est ce vraiment ?
    Par ZeKiD dans le forum Langage
    Réponses: 17
    Dernier message: 24/01/2006, 17h22

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