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 :

Comportement étrange avec l'utilisation de Datagridview.Rows.clear() [Débutant]


Sujet :

VB.NET

  1. #1
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut Comportement étrange avec l'utilisation de Datagridview.Rows.clear()
    Bonsoir,

    je rencontre un problème avec datagridview.Rows.clear() (Frameworkk .Net 3.5) que je n'arrive pas à solutioner.

    Je dispose d'un treeview que je charge à l'aide d'un fichier. Dès que je clique sur un bouton "tester" je parcours chaque noeux du treeview et j'ajoute une ligne au tableau. Donc si j'ai "12 noeux" au treeview je dois avoir 12 lignes au tableau.

    Treeview :

    nodes(0)
    nodes(0).nodes(0)
    nodes(0).nodes(1)
    ....
    nodes(0).nodes(11)

    Salle_A
    |______ Ordinateur_1
    |______ Ordinateur_2
    |______ Ordinateur_3

    |______ Ordinateur_12

    J'obtiens le résultat souhaité. Sauf que je suis confronté à un comportement aléatoire. Je m'explique, si je clique 8 fois sur le bouton "tester", le tableau me charge correctement les 12 lignes correspondantes au 12 noeux du treeview. Au 9è click ou 10è (celà peux être plus ou moins de fois), le tableau affiche les 12 lignes correctement et y ajoute à nouveau ces 12 même lignes. Je ne comprend pas pourquois.

    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
    Private Sub btn_tester_Click()
       load_tv()
       check_ordi()
    End Sub
     
    Private Sub check_ordi()
     
            If dgv.Rows.Count = 0 Then
     
                Dim i As Integer = 0
                While i < tv.Nodes(0).Nodes.Count
                   //appel de la fonction pour ajouter une ligne au tableau
                    i += 1
                 End While
     
             Else
                  dgv.Rows.clear()
                  check_ordi()
              End if
     
    End Sub

    Pour comprendre le problème j'affiche la valeur de i dans un label. Je peux donc constater son incrémentation. Par exemple, je clique 8 fois sur le bouton "tester", i s'incrémente bien de 0 à 11 (11 étant toujours le maximun). Au neuvième click, i passe de 0 à 11 puis est réinitialisé à 0 à ce moment là, le programme àjoute donc 12 nouvelles lignes au tableau et je me retrouve donc avec 2 fois 12 lignes.

    Je ne comprend pas à quel moment i est réinitialisé à 0 alors que j'atteinds tv.Nodes(0).Nodes.Count.

    Code complet :

    Note Lorsque je teste Me.isLocal = False.

    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
     
    Private Sub check_ordi()
            Dim i As Integer = 0
     
            If dgv.Rows.Count = 0 Then
     
                While i < tv.Nodes(0).Nodes.Count
                    lbl_count.Text = i
                    If is_online(tv.Nodes(0).Nodes(i).Name) Then
     
                        If Me.isLocal Then
                            run_process(Me.tv.Nodes(0).Nodes(i).Name)
                            import_csv()
                            Me.load_gdv()
                        Else
     
                            dgv_ordi(Me.tv.Nodes(0).Nodes(i).Name, i)
     
                        End If
                        tv.Nodes(0).Nodes(i).BackColor = Color.GreenYellow
                        dgv.Rows(i).DefaultCellStyle.BackColor = Color.GreenYellow
                    Else
                        dgv_ordi(Me.tv.Nodes(0).Nodes(i).Name, i)
     
                        tv.Nodes(0).Nodes(i).BackColor = Color.LemonChiffon
                        dgv.Rows(i).DefaultCellStyle.BackColor = Color.LemonChiffon
                    End If
                    Application.DoEvents()
                    i += 1
                End While
     
            Else
     
                dgv.Rows.Clear()
                Me.check_ordi()
            End If
    End Sub
     
     
    ' cette procédure va ajouter seulement une ligne au tableau :
    ' je regarde la valeur du noeux (Nodes(0).Nodes(i).Name)
    ' et lance une recherche dans un dictionaire contenant une liste 
    ' d'ordinateur chargés à partir d'un fichier
    Private Sub dgv_ordi(ByVal Ordip As String, ByVal i As Integer)
     
         Dim nom, ip, mac as String
         ip=""
         mac=""
         nom=""
     
           For Each kpv As KeyValuePair(Of String, Dictionary(Of String, String)) In Me.dicOrdi
     
                If kpv.Key = Ordip Then
                    For Each k As KeyValuePair(Of String, String) In kpv.Value
                        Select Case k.Key
                            Case "nom"
                                nom= k.Value
                            Case "ip"
                                ip = k.Value
                            Case "mac"
                                mac = k.Value
     
                        End Select
                    Next
     
                    Dim line = New String() {"text", "text", "text", "text", nom, ip, mac, "text"}
                    dgv.Rows.Add(line)
     
                End If
            Next
     
     
    End Sub
    Je vous remercie d'avance pour votre aide!

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    je vote pour le doevents ; c'est à proscrire, ca peut faire bugger tout et n'importe quoi
    dans les faits, pendant le doevents, si tu cliques sur le bouton à nouveau ca appelle la sub, et à la fin de celle ci, l'exécution du 1er clic suspendu reprend au niveau du doevents, donc plus de 12 lignes
    avec doevents on peut faire crasher une appli aussi en cliquant sur fermer la fenetre, le doevents reprend après le code disant me.treeview.x sauf que la fenetre étant fermée le treeview n'existe plus



    après
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    sub 1
    si lignes = 0 alors
       remplir
     sinon
       vider
       rappeler sub 1 (donc remplir)
    ca peut se simplifier

    et au lieu d'un while i, i+=1 on peut faire for i
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    je vote pour le doevents ; c'est à proscrire, ca peut faire bugger tout et n'importe quoi
    dans les faits, pendant le doevents, si tu cliques sur le bouton à nouveau ca appelle la sub, et à la fin de celle ci, l'exécution du 1er clic suspendu reprend au niveau du doevents, donc plus de 12 lignes
    avec doevents on peut faire crasher une appli aussi en cliquant sur fermer la fenetre, le doevents reprend après le code disant me.treeview.x sauf que la fenetre étant fermée le treeview n'existe plus

    après
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    sub 1
    si lignes = 0 alors
       remplir
     sinon
       vider
       rappeler sub 1 (donc remplir)
    ca peut se simplifier

    et au lieu d'un while i, i+=1 on peut faire for i
    Merci pour ta reponse. J'ai aussi pense au doevents et pens´e que j'avais trouv´e le bug mais les essais que j'avais fait n'avaient pas ete concluant. Ici j'utilise le doevents pour forcer l'affichage et surtout voir la progression de l'affichage des couleurs de chaque/noeux en fonction du resultat de is_online(ip). Si je n'utilise pas doevents et je clique sur le bouton "tester" je vois donc maintenant un treeeview vide et le tableau l'est egaelement au lieux de voir ces deux element se remplir noeux/ligne par noeux/ligne. Ma methode / approche n'est peut etre pas la bonne ?? Est-il possible de voir mon treeview et mon tableau se charger en meme temps pas a pas tout en affichant une couleur de noeux/ligne differente en fonction du resultat is_online() ?

    Pour la boucle for a la place du while, qu'est-ce que le for apporte de mieux que le while ici? Jj'essai de faire un For i as integer to tv.Nodes(0).Nodes.Count mais cela ne fonctionne pas car le treeview n'est pas encore remplit jusqu' a la fin je suppose (du a la suppresion du doevents.

    Merci !

    ps : pardon pour les accents.

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    le for apporte plus de lisibilité, ca gagne une ligne de code et le while est plus utilisé avec un test
    en voyant un for on sait directement qu'on va faire x tours

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
       For Each k As KeyValuePair(Of String, String) In kpv.Value
                        Select Case k.Key
                            Case "nom"
                                nom= k.Value
                            Case "ip"
                                ip = k.Value
                            Case "mac"
                                mac = k.Value
     
                        End Select
    totalement inutile, enfin mauvaise utilisation donc ca fait du code moche
    essaye de faire une classe plutot (avec 3 propriétés nom ip mac)


    après je ne comprends pas ta question "Est-il possible de voir mon treeview et mon tableau se charger en meme temps pas a pas tout en affichant une couleur de noeux/ligne differente en fonction du resultat is_online"
    tout est possible, par contre pour t'expliquer il faut qu'on sache ce que tu fais

    ton traitement est long dans la boucle while ?
    si oui tu peux voir le backgroundworker
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    le for apporte plus de lisibilité, ca gagne une ligne de code et le while est plus utilisé avec un test
    en voyant un for on sait directement qu'on va faire x tours

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
       For Each k As KeyValuePair(Of String, String) In kpv.Value
                        Select Case k.Key
                            Case "nom"
                                nom= k.Value
                            Case "ip"
                                ip = k.Value
                            Case "mac"
                                mac = k.Value
     
                        End Select
    totalement inutile, enfin mauvaise utilisation donc ca fait du code moche
    essaye de faire une classe plutot (avec 3 propriétés nom ip mac)


    après je ne comprends pas ta question "Est-il possible de voir mon treeview et mon tableau se charger en meme temps pas a pas tout en affichant une couleur de noeux/ligne differente en fonction du resultat is_online"
    tout est possible, par contre pour t'expliquer il faut qu'on sache ce que tu fais

    ton traitement est long dans la boucle while ?
    si oui tu peux voir le backgroundworker

    Je suis d'accord avec toi pour le code ci-dessus. De toute facon ce code est temporaire c'est juste pour du test et je comptais comme tu le recommande faire une classe a part pour plus de lisibiliter et ne laisser dans cette classe que le code qui gere l affichage. Je decouvre pleins de chose en meme temps, surtout VB.net que je ne connais/maitrise pas du tout.

    Ce que je souhaite faire :

    Des que je clique sur un bouton "tester", chaque noeux du treeview doit afficher une couleur differente : verte si le ping a reussi, rouge si le ping n a pas reussi. De ce fait je sait quel ordinateur et joignable ou pas. Il s'en suit aussi en meme temps l affichage du tableau (au passage je ne sais pas si je dois lier le tableau a une source de donnee car je fonctionne avec des fichiers csv.). Chaque ligne est aussi affichee en vert ou bien en rouge. Ceci je souhaite le voir de facon progressive. Au debut j'avait penser a une barre de progression puis je n'arrivais pas a gerer la progression comme je voulais. Et je suis tombe sur un forum sur l'utilisation du doevents qui semblais repondre a mon besoin. Or cette solution n'est pas recommandee. En faisant une recherche, j'ai pu lire que l'utilisation de backgroundworker ou de thread est plus que conseillee. Je ne sais pas trop comment tout cela fontionne.

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    pour le rafraichissement, le principe va être de le faire tous les tant de temps, pour ca il y a le timer ou le thread (le backgroundworker est un thread légèrement simplifié, mais pour une boucle continue le thread est peut etre conseillé)
    le timer ca se peut se poser sur un form comme un bouton (ou presque), il lève ensuite un event toutes les x millisecondes, sur le thread principal, permettant donc de modifier l'interface

    le truc c'est que pendant que notre code s'exécute l'interface n'est pas rafraichie, donc si le code est long (plusieurs centaines de millisecondes) l'interface freeze ("ne répond pas")
    le doevents permet dans certains cas de pallier à ce problème, mais comme dit précédemment c'est une fausse bonne idée
    par contre si on effectue notre traitement long sur un autre thread, il n'y a pas de freeze
    nouvel inconvénient, il est interdit de modifier l'interface depuis un autre thread (changer la couleur d'un treenode par exemple)
    il y a alors des mécanismes pour revenir sur le thread principal le temps de modifier l'interface

    sur la classe ping, il y a plusieurs méthodes pour faire un ping
    il y a le ping simple, le ping avec un timeout (si le ping ne répond pas dans ce laps de temps, le ping est déclaré en échec), et le ping asynchrone

    les méthodes asynchrones il y en a un peu partout dans le framework, ca peut faire peur au début mais une fois qu'on a compris c'est simple
    en fait la méthode qu'on appelle démarre un thread pour faire ce qu'elle doit faire, et quand elle a fini elle fait le retour
    il y a 2 patterns, soit celui de l'event (simple), soit celui du callback
    le callback ca revient au même, quand on appelle une méthode on lui donne un pointeur vers une sub qu'on veut qu'il rappelle quand c'est terminé
    dans les 2 cas on peut souvent passer un objet, qui nous permettra de savoir sur quoi porte le rappel


    pour résumer, tu poses un timer à 1000ms
    quand ton dictionnaire est rempli tu fais letimer.start
    sur l'event tick du timer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for each pc in ledico.values
      dim p as new system.net.networkinformation.ping  
      addhandler p.pingcompleted, addressof pingterminé
      p.sendasync(pc.ip, 500, pc) ' ici on passe l'instance du pc 
    next
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    private sub pingterminé (sender As Object, e As System.Net.NetworkInformation.PingCompletedEventArgs)
      Dim p As System.Net.NetworkInformation.Ping = DirectCast(sender, System.Net.NetworkInformation.Ping) ' dans toutes les méthodes, sender est celui qui appelle l'évènement
     RemoveHandler p.PingCompleted, AddressOf a ' les handlers ajoutés doivent être suprimés
      dim lepc as pc = directcast(e.userstate, pc) ' ce qu'on a mis en dernier dans sendasync est récupérable ici
      '  le statut du ping se trouve via  If e.Reply.Status = Net.NetworkInformation.IPStatus.Success Then
       ' on a donc le pc, l'état du ping, il ne reste plus qu'à retrouver le node et la ligne du dgv pour change la couleur
      ' le retour de la méthode async est sur le même thread que l'appel (dans le timer) donc sur le thread principal, donc l'interface est modifiable d'ici
    end sub
    voilà, j'espèce que je t'ai bien assomé
    j'ai peut etre tiré quelques raccourcis dans mes explications, n'hésites pas si tu as des questions
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Merci pour le coup de massue !
    Dis moi , qu'en est-il du backgroundworker ? j'etais en train de lire la documentation a ce sujet.

    Il y a quelque chose que je ne comprend pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Dim p As System.Net.NetworkInformation.Ping = DirectCast(sender, System.Net.NetworkInformation.Ping)
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    RemoveHandler p.PingCompleted, AddressOf a
    Que represente " AddressOf a "dans ton code ?

    Pourquoi choisir 1000 ms pour le timer et pas plus ou moins? Comment trouver la juste valeur ?

  8. #8
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    addressof uneméthode sert à faire un pointeur vers une méthode

    quand tu poses un bouton sur une form, et que tu doubles clic sur le bouton, tu arrives dans le code dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private sub button1_click (sender as object, e as system.Eventargs) handles button1.click
    handles signifie que l'évènement click de button 1 va appeler cette sub
    quand le code est compilé, le handles est transformé, le code final contient
    addhandler et removehandler

    quand on créé un bouton par le code (par exemple si on veut poser 10 boutons)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for i as integer = 1 to 10
      dim b as new button
      b.left = i*40
      me.controls.add(b)
      addhandler b.click, addressof laméthodequigèreleclick
    next
    car c'est bien gentil de créer des boutons, mais gérer leur click c'est mieux, le addhandler sert à ca (addhandler instance.event, addressof méthode)

    comme on le voit dans l'event click d'un bouton posé, il y a 2 arguments, sender et e
    tous les évènements du framework possèdent sender et e
    sender est toujours celui qui déclenche l'event
    e est une variable qui contient les paramètres de l'evènements, son type change, mais il hérite toujours de system.Eventargs
    pour mousemove par exemple, sender va être de type mouseeventargs, il contient le x et le y (e.x et e.y) de l'emplacement du curseur

    une méthode peut etre utilisé pour gérer différents évènements, donc sender peut etre un bouton, un label ou autre chose
    il est donc déclaré as object (= il peut contenir n'importe quel type)
    même si tu sais que c'est un bouton, visual studio ne voudra pas que tu écrives sender.text = "nouveau text"
    il faut donc lui dire que tu veux récupérer une variable de type bouton contenu dans sender, on appelle ca "caster"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dim b as button = directcast(sender, button) ' directcast(instance, type)
    biensur si sender contient un label ca va planter, pour vérifier le type il y a typeof
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if typeof sender is button then
      '...
    end if
    pour les 1000ms du timer, c'est au choix entre 16ms et beaucoup
    ca dépend donc de ce que tu veux y faire
    avoir l'info du ping toutes les demies heures, ce n'est pas forcément génial
    faire un ping toutes les 30 ms ca me parrait un peu trop
    ici pour du ping toutes les secondes ca me parrait pas trop mal, mais c'est à toi de choisir

    je te parles donc de concepts utiles dans .net, ce n'est peut etre pas grave si tu ne comprends pas tout tout de suite, mais au moins tu l'aurais lu et en avancant un peu dans l'apprentissage tu comprendras
    un truc à lire aussi, qui explique pas mal de choses : http://plasserre.developpez.com/cours/vb-net/
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  9. #9
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    J'ai beaucoup de mal a comprendre ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dim lepc as pc = directcast(e.userstate, pc)
    D'ou vien l'objet "pc" il n'est pas declare dans ta fonction. De plus ici pc est aussi un type puisque tu specifies "as pc" Je n arrive pas a faire le lien avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    p.sendasync(pc.ip, 500, pc) ' ici on passe l'instance du pc
    Merci bien!

    Edit : J'ai trouve ! en fait cette ligne dans mon cas fonctionne pas, j ai procede comme suivt :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    p.sendasync(pc.ip, 500, pc) 
    Dim pc As Dictionary(Of String, String) = e.UserState
    Ensuite je fais le test comme tu as dis et je met les bonnes lignes du tableau et les noeux correspondant en vert si le ping a reussi !.

    J'ai beaucoup modifie mes classes et je sent que c est plus clair, lisible et un peu plus performant !

  10. #10
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    pas tout compris tu as encore des interrogations ou c'est bon et tout marche ?
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  11. #11
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    pas tout compris tu as encore des interrogations ou c'est bon et tout marche ?
    Ca fonctionne. J'ai le resultat souhaite. J'avais pas compris cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    dim lepc as pc = directcast(e.userstate, pc)
    Ici dans mon cas elle ne s'applique pas car pc est un dictionnaire. Mais je pense que tu as du prendre un raccourci pour m'expliquer de facon plus generale le concept pour recuperer la valeur de pc.

    Ce que je fais c est que j'ai mis timer.start() dans la fonction du bouton "tester". Des que je clique dessus le timer demarre, je recharge mon treeview et je fais un timer.stop juste apres.

    Sauf que j'ai l'impression que le timer tourne toujours. Je dispose d'une fenetre que j'appele par un menu (une fenetre "parametre" classique). Cette fenetre me permet de decider si je souhaite faire un ping sur localhost ou vers plusieurs ordinateur. Quand je passe d'un etat a l autre aleatoirement, j ai une erreur de type : TargetInvocationException was unhandeled. Et ca me fait literalement plater mon programme. Le programme s'arrete.

    Je pensais que cela venait d'un .Rows.clear() ou d'un autre rafraichissement a la fermeture de la fenetre "parametres", en fait il n'en est rien. Il semble que le timer soit toujours actif car je peux voir que le premier noeux du treeview est colore alors que je n'ai pas encore clique sur le bouton "tester" pour l'activer...

  12. #12
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    Citation Envoyé par iOops Voir le message
    Ce que je fais c est que j'ai mis timer.start() dans la fonction du bouton "tester". Des que je clique dessus le timer demarre, je recharge mon treeview et je fais un timer.stop juste apres.

    je t'ai proposé le timer pensant que le ping devait être fait souvent et automatiquement pour mettre à jour l'état
    si tu ne dois le faire que sur un bouton, le timer n'a pas lieu d'être, il faut coder directement dans le button.click

    Citation Envoyé par iOops Voir le message
    j ai une erreur de type : TargetInvocationException was unhandeled. Et ca me fait literalement plater mon programme. Le programme s'arrete.
    il faut mettre des try catch autour de tout code qui peut planter (donc presque tout)
    dans le catch (mais aussi en cas d'erreur non catchée dans visual studio) tu auras les détails de l'erreur (ligne qui passe en erreur dans le code, pile des appels (stacktrace), type d'erreur etc...)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  13. #13
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    je t'ai proposé le timer pensant que le ping devait être fait souvent et automatiquement pour mettre à jour l'état
    si tu ne dois le faire que sur un bouton, le timer n'a pas lieu d'être, il faut coder directement dans le button.click



    il faut mettre des try catch autour de tout code qui peut planter (donc presque tout)
    dans le catch (mais aussi en cas d'erreur non catchée dans visual studio) tu auras les détails de l'erreur (ligne qui passe en erreur dans le code, pile des appels (stacktrace), type d'erreur etc...)
    D'accord. Je vais tout mettre dans la gestion du bouton a cliquer. Il semble que je soit parvenu a fixer l'erreur en faisant un timer.stop() dans la fonction au moment ou ma fenetre parametre se ferme. Mais ce n'est pas une methode propre je pense. Je vaias adapter avec ce que tu as dit.

  14. #14
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Du coup je me retrouve dans la situation de depart en fait non?
    Je doute que le ping.sendasync me permette de faire en sorte que je n'ai pas un treeview tout blanc en attendant le resultat du ping et l afficher de facon coloree.

    Dans ce cas dois-je passer cette tache a un backgroundworkder, pour faire en sorte que l'utilisateur ne voit pas un treeview completement vide le temps que le resultat arrive, mais qu il puisse voir la progression du ping sur chaque noeux et que le resultat s'affiche ligne par ligne dans le tableau?

  15. #15
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    non
    tu mets le code du timer.tick dans le code du button.click
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  16. #16
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut [ Resolu ] Comportement étrange avec l'utilisation de Datagridview.Rows.clear()
    Pol63, je te remercie pour tes explication j'ai beaucoup avance et decouvert quelque chose de nouveau !

    J'ai donc mis le code dans la gestion du bouton et j'ai reduit le timeout a 120 pour lever l'erreur du timeout. Donc maintenant mon treeview et mon tableau s'affiche de deux couleurs differente en fonction de l'etat de l'ordinateur distant.

    Merci encore,

    Bonne soiree !

  17. #17
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    J'ai une nouvelle question au sujet du Ping.SendAsync alors je ne pense pas qu'il soit utile de poster un autre sujet alors qu'il s'agit du meme projet.

    Je suis assez content de la fonction enoncee ci-dessus qui me permet de pinger plusieurs adresses ip. Maintenant j'ai mis en place la gestion des hostnames. Cela fonctionne a peu pres comme je veux. A peu pres car dans le cas ou le ping de l'hote a echoue car il est inconnu ou injoignable je ne parviens pas a recuperer l'erreur et traiter le resultat comme je le veux.

    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
    Private dStatus as new Dictionary(of String, boolean)
     
    Private Sub ping(ByVal machines As List(Of String))
     
            For i As Integer = 0 To (machines.Count - 1)
     
                Dim p As New System.Net.NetworkInformation.Ping
                AddHandler p.PingCompleted, AddressOf ping_end
                p.SendAsync(machines(i), 102, machines(i))
     
            Next
     
        End Sub
     
    Private Sub ping_end(ByVal sender As Object, ByVal e As System.Net.NetworkInformation.PingCompletedEventArgs)
     
            Dim ping As System.Net.NetworkInformation.Ping = DirectCast(sender, System.Net.NetworkInformation.Ping)
            RemoveHandler ping.PingCompleted, AddressOf ping_end
     
            If Not e.Error Is Nothing Then
     
                  # hote inconnu et/ou injoignable
     
                dStatus.Add(e.UserState, False)
     
            ElseIf e.Reply.Status = NetworkInformation.IPStatus.Success Then
     
                dStatus.Add(e.UserState, True)
     
            ElseIf e.Reply.Status = NetworkInformation.IPStatus.TimedOut Then
     
                dStatus.Add(e.UserState, False)
     
            End If
        End Sub
    Si le ping a reussi ou bien que j'ai un timeout je peux constater que mon dictionnaire se remplit correctement. Cependant si le nom de l'hote est inconnu ou injoignable, je rentre bien dans la condition : If Not e.Error Is Nothing . C'est a ce moment que j'ai un comoportement aleatoire. Parfois il va a la ligne suivante et fait le dStatus.add et ensuite le programme semble s'arreter. Parfois il ne fait pas le dStatus.add. Je me suis dit que etant donne que dans e.Error l'execption Sockets.SocketExeception est levee et que je ne la gere pas avec un try ... catch il est normal que je ne recupere jamais la valeur de mon dStatus.Add(e.UserState, False). Or j'ai essayer le try .. catch comme ceci :

    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
    Private Sub ping(ByVal machines As List(Of String))
     
            For i As Integer = 0 To (machines.Count - 1)
     
             try
     
                      Dim p As New System.Net.NetworkInformation.Ping
                      AddHandler p.PingCompleted, AddressOf ping_end
                      p.SendAsync(machines(i), 102, machines(i))
     
             catch ex as Sockets.SocketExecption
     
             end try
     
                      dStatus.Add(machines(i), False)
     
            Next
     
        End Sub
    ... mais cela n'a aucun effet.

    Par exemple si je fais un test avec deux hotes, l'un existe et l'autre pas. A la fin du traitement du ping j'obtiens toujours le meme resultat. le dStatus.Count est toujours egal a 1, et le dStatus contient uniquement le nom de l'hote pinge avec succes.

    Merci d'avance !

  18. #18
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    erreur basique qui peut s'éviter en suivant les best pratices

    quand on fait un select cas ou des if, il faut toujours gérer le ELSE

    dans ton cas s'il n'y a pas d'erreur ni un success ni un timeOut tu ne passes nulle part (j'ai testé dans certains ca c'est un autre valeur d'enum qui passe unreachable je crois)


    concernant le e.Error, ce n'est qu'une variable as Exception, pas une Exception
    dans le code du pingAsync dans le framework il y a un try catch, si ca passe dans le catch l'exception est mise dans cette propriété et n'est pas propagée plus loin
    (pour rappel le framework est codé en .net)
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  19. #19
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 48
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    erreur basique qui peut s'éviter en suivant les best pratices

    quand on fait un select cas ou des if, il faut toujours gérer le ELSE

    dans ton cas s'il n'y a pas d'erreur ni un success ni un timeOut tu ne passes nulle part (j'ai testé dans certains ca c'est un autre valeur d'enum qui passe unreachable je crois)


    concernant le e.Error, ce n'est qu'une variable as Exception, pas une Exception
    dans le code du pingAsync dans le framework il y a un try catch, si ca passe dans le catch l'exception est mise dans cette propriété et n'est pas propagée plus loin
    (pour rappel le framework est codé en .net)
    Quelque chose comme ca ? :

    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
    If e.Error Is Nothing Then
                If e.Reply.Status = NetworkInformation.IPStatus.Success Then
     
                    dStatus.Add(e.UserState, True)
     
                ElseIf e.Reply.Status = NetworkInformation.IPStatus.TimedOut Then
     
                    dStatus.Add(e.UserState, False)
     
                ElseIf e.Reply.Status = NetworkInformation.IPStatus.DestinationHostUnreachable Then
     
                    dStatus.Add(e.UserState, False)
     
                Else
     
                    dStatus.Add(e.UserState, False)
     
                End If
    Else
         dStatus.Add(e.UserState, False)
    End If
    En tout cas apres essai, j'ai le meme resultat. Parfois ca marche si je lance le pas a pas avec le debugger mais ce n'est ps 100% des cas.

  20. #20
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 199
    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 199
    Par défaut
    étonnant chez moi ca fonctionne bien
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. [Lazarus] Problème étrange avec l'utilisation de la fonction StrToFloat
    Par ovni76 dans le forum Lazarus
    Réponses: 7
    Dernier message: 07/09/2014, 18h01
  2. Réponses: 0
    Dernier message: 02/07/2013, 11h53
  3. Comportement étrange avec "order by"
    Par Warluck dans le forum SQL
    Réponses: 2
    Dernier message: 04/11/2010, 21h06
  4. Comportement étrange avec free.
    Par Rakken dans le forum C
    Réponses: 9
    Dernier message: 17/09/2008, 14h06
  5. Comportement étrange avec les index et "order by"
    Par Dia_FR dans le forum Requêtes
    Réponses: 5
    Dernier message: 18/08/2008, 09h18

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