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

Windows Forms Discussion :

[VB.net] Question simple sur les Timers


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2004
    Messages : 100
    Par défaut [VB.net] Question simple sur les Timers
    Salut à tous,

    Dans une de mes applis, je dois effectuer des vérifications constamment et effectuer des actions en conséquence. J'utilise plusieurs Timers et dans mon étape débogage, je me suis demandé si un Timer passe en priorité l'exécution complète de son code ou son Intervale ?

    En d'autres mots, si j'ai beaucoup de code dans un timer qui a un intervale de 100ms, est-ce qu'il va prendre le temps de finir ce qu'il a commencer ou si ça lui prend plus de temps, il va sans cesse répéter les premières lignes de code et ignorer le reste ?

    En plus clair,


    non je rigole...

    Quelqu'un a une idée ?

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    ca serait quand meme grave si ca s'arretait au bout de quelques lignes, et personne ne développerait sous .net !!

    prenons un timer à 2 secondes et 3 secondes de traitement
    S0 le timer se déclenche, le code commence à s'executer
    S2 au bout de 2 secondes, le timer se redéclenche alors que l'evenement n'est pas fini, l'evenement est mis en attente sur la pile des appels, le code d'origine continue de s'executer
    S3 une seconde plus tard, le premier appel se termine, le programme reprend la main et regarde sur la pile des appels s'il y a quelque chose à faire, en l'occurrence oui, appeler la sub de l'évènement
    S3 la sub redémarre donc pour 3 secondes de traitement (sans attendre 2 secondes)
    S4 le timer se redéclenche, comme à S2, l'appel se met sur la pile
    etc...

    si on continue on peut imaginer que le timer allant toujours plus vite que son traitement, il va y avoir des centaines d'appels dans la pile
    fait "rassurant", ce n'est pas le cas
    apparemment le timer ne laisse pas plus de 2 appels sur la pile, sinon ca finirait par déborder et génerer un stackoverflowexception


    le timer windows forms est sur le thread principal
    sur un thread le code ne s'execute qu'à un endroit à la fois
    quand 3 evènement se produisent en meme temps, ils sont mis sur une pile, et le programme dépile pour executer les sub liés aux évènements

    dans l'exemple que je donne, le programme sera fortement ralenti, car pendant que du code s'execute l'interface est figée (vu que le code ne s'execute qu'à un endroit à la fois, sur un traitement long, l'interface utilisateur ne peut meme pas se redessiner)
    en tout cas il n'y a plus de temporisation, l'appel se faisant directement après la fin de l'execution

    certains mettent timer.stop au début de la sub et timer.start dans le finally d'un try catch
    m'enfin pour des traitements lourds, il vaut mieux faire un thread séparé, plus performant, et ne figeant pas l'interface utilisateur (voir backgroundworker par exemple)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Octobre 2008
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2008
    Messages : 83
    Par défaut
    Justement je rebondis sur ce sujet.
    J'utilise aussi les timers pour scruter des évenements extérieur au code du pc (carte d'entrées/sorties notament)
    J'utilise aussi le timer.stop() en début de code et je termine par timer.start()
    sachant que je scrute toutes les 100ms en moyenne avec 8 instructions de 10ms chaque cela devient inutile. Sauf que je travail via une dll sur le port USB et le temps de 10ms n'est pas garanti.

    Pour faire simple que ce passe t'il si le code à faire est suppérieur a l'interval ?
    Et pour conclure, quel est alors la différence entre timer.enabled et timer.start ?
    Merci pour votre réponse.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    timer.Start fait timer.enabled = true
    (tout comme uneform.show fait uneform.visible = true ^^)

    si le temps de traitement du timer est plus long que l'interval, 2 cas (comme je l'explique avant)
    s'il n'y a pas de timer.stop, le code est executé en continue en gros
    s'il y a un timer.stop, il y a bien une pause défini par l'interval, malgré que le traitement agrandi cet interval

    pour gérer des choses qui arrivent souvent, comme des IO dans ton cas, en général il est préférable de faire un thread séparé, surtout que de nos jours, il y a plusieurs core sur un processeur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    private sub peu_importe (au démarrage de l'appli par exemple)
      dim th as new system.threading.thread(adressof sub_traitement)
      th.isbackground = true ' permet d'éviter que le processus ne s'arrete pas
      th.start
    end sub
     
    private sub sub_traitement
      while true
        'traitement
        system.threading.thread.sleep(100)
      end while 
    end sub
    ce code équivaut un peu à un timer, une fois le traitement effectué, ca attend 100ms

    avoir plusieurs thread sur un programme équivaut à avoir plusieurs lignes d'execution de code qui avancent en meme temps (visible sur le débugage pas à pas)


    autre exemple, si on a une appli qui dialogue par tcp/ip, on peut avoir une collection qui contient les transferts à effectuer
    le code de l'interface utilisateur ajoute un element à la collection (en général un system.collections.generic.queue(Of ) et un thread s'occupe de transférer

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    private sub thread_envoi
      while true 
        if queue.count = 0 then
          system.threading.thread.sleep(100)
          continue while
        end if
        ' code du transfert, avec un queue.dequeue()
      end while
    end sub
    avec ce code, s'il n'y a rien à envoyer, on ne fait rien et on remonte au début du while
    tant qu'il y a des choses à envoyer, ca envoie sans attendre
    le fait de déporter sur un thread permet de le faire bosser à fond sans bloquer l'interface utilisateur, qui est gérée par le thread principal

    il existe aussi un timer qui n'est pas dans le namespace system.windows.forms, celui ci renvoi son evenement sur un thread séparé, et donc si on ne fait pas de timer.stop la pile des appels peut grandir si le traitement est plus long que l'interval, et l'appli peu planter


    NB : penser à mettre les try catch au bon endroit pour etre sur que le thread ne s'arrete pas, arretant ainsi la fonction qu'il occupait
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre éclairé
    Homme Profil pro
    Architecte technique
    Inscrit en
    Octobre 2008
    Messages
    83
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2008
    Messages : 83
    Par défaut
    Merci bien pour ce bon tuto.
    En fait j'utilse déja les treads mais pour la gestion du grafcet de process (avec un speudo chien de garde)
    Mais en effet rien de m'empéche d'en creer un second pour l'écriture des IO.
    Note que j'utilise les timer pour les IO car il n'y aucune chance que le timer bloque ou plante l'hmi. Mais je vais suivre ton conseil.
    Note que j'ai eu un peu de mal à enchanger des variables inter tread, et je dois encore utiliser le checkforillégal = false pour éviter les soucis.
    voici le principe que j'utilise peut être que j'oubli un truc ?
    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
    Dim Grafcet As New System.Threading.Thread(AddressOf Th_Grafcet) ' Declare le thread du grafcet
     
    ' dans le form closing :
            ' tue le thread si actif
            If (Grafcet.IsAlive) Then Grafcet.Abort()
     
    'donc le form load :
            ' Pour annuler une erreur inter/thread
            CheckForIllegalCrossThreadCalls = False
    Grafcet.Start()
     
    'puis enfin le début de son code:
     Sub Th_Grafcet()
            While True  ' a faire tant que mode auto vrai
     
                If Num_Etape > 0 And Num_Etape < 6 And ReadDigitalChannel(1) = False Then
                    LblIdProd.Text = "TEST Annulé Bimanuelle relaché" 'si un prod selectionné
                    LblIdProd.Refresh()
                    Me.BackColor = Color.Orange ' couleur de fond en orange
                    Pause(500)
                    Num_Etape = 0
                End If
     
     
                Application.DoEvents() ' sans bloquer le reste de l'appli
    ' dois servir à rien puisque pas dans le tread principal ???
    ' en revanche rajout d'une pause de 100ms pour redonner la main au tread principal
                Select Case Num_Etape
     
                    '---------------------INIT DU GRAFCET ET ATTENTE SELECTION PRODUIT--------------------
                    Case 0 ' init...... etc....
    Voila si tu vois une bétise, je serais ravi de la connaitre, d'avance merci pour ta critique
    cordialement

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    .abort c'est moyen
    CheckForIllegalCrossThreadCalls = False c'est vraiment déconseillé
    Application.DoEvents ca serait mieux de l'éviter aussi


    pour le .abort, il vaut mieux essayer de passer par un booléen qui arrete proprement en attendant, et .interrupt serait peut etre meme mieux, le .abort déclenche une erreur, qui peut se produire dans le framework et donc avoir des effets de bords ...


    en multithreading, seuls les controles ne peuvent etre modifiés que par un thread (le thread principal)
    la méthode quand on est sur un thread autre c'est de passer par délégué
    j'ai expliqué les threads et les délégués dans ce post
    http://www.developpez.net/forums/d49...es-difference/
    dans lequel je fais meme un lien vers moi meme avec un exemple plus complet des délégués

    les autres variables (non graphiques donc) peuvent etre manipulées par tout le monde
    par contre ca peut poser des soucis
    sur une collection, si un thread fait .Add pendant qu'un autre fait For Each dessus ca plante
    il y a des moyens de sécuriser du multithreading (synclock, readerwriterlock ...)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

Discussions similaires

  1. [Débutant] Question simple sur les checkbox
    Par Mil17 dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 01/08/2007, 15h05
  2. [MySQL] Question simple sur les tableaux pour un initié
    Par bom8407@hotmail.com dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 01/03/2007, 11h22
  3. Réponses: 4
    Dernier message: 16/11/2006, 02h10
  4. question simple sur les select dynamiques
    Par grinder59 dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 24/01/2006, 15h53
  5. Question simple sur les threads :)
    Par momox dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/06/2003, 04h13

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