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 :

Transposition en thread [Fait]


Sujet :

Windows Forms

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut Transposition en thread
    Bonsoir,

    Apres une grosse semaine de recherche et test en tout genre, je n'arrive tjrs à transformer ce bout de code afin qu'il fonctionne via un multi thread.
    Je m'explique, j'ai des valeurs que je recup dans un listview. Ce dernier comprends x ligne. Pour le moment je passe par un seul thread qui est le main (d'après ce que je comprends) et c'est très lent. J'aurais voulu utiliser le mult thread afin d'augmenter la vitesse de traitement.

    Je vous donne le code de ce que j'utilise actuellement :

    Sub appelée :
    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
     
    Private Sub DNS_Res(ByVal Compteur As Integer)
            Dim Compteur As Integer
            Dim Host_Name As String
            Dim Host_IP As String
     
            For Compteur = 0 To (NbL_DNS - 1)
                Host_Name = LV_DNS.Items(Compteur).SubItems(1).Text
                Host_IP = LV_DNS.Items(Compteur).SubItems(2).Text
     
                Dim Th_DNS = New Thread_DNS_Class(Host_Name, Host_IP)
     
                LV_DNS.Items(Compteur).SubItems(3).Text = Th_DNS.DNS_Resolution_Result()
                Select Case Th_DNS.DNS_Resolution_Result()
                    Case "Resolved"
                        LV_DNS.Items(Compteur).SubItems(3).ForeColor = Color.Green
                    Case "Not Resolved"
                        LV_DNS.Items(Compteur).SubItems(3).ForeColor = Color.Red
                    Case Else
                End Select
     
                LV_DNS.Items(Compteur).SubItems(4).Text = Th_DNS.DNS_Reverse_Result()
                Select Case Th_DNS.DNS_Reverse_Result()
                    Case "Resolved"
                        LV_DNS.Items(Compteur).SubItems(3).ForeColor = Color.Green
                    Case "Not Resolved"
                        LV_DNS.Items(Compteur).SubItems(3).ForeColor = Color.Red
                    Case Else
                End Select
            Next
     
        End Sub
    et la public classe que j'ai ecrite
    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
     
    Imports System.Net
    Imports System.Net.Dns
    Public Class Thread_DNS_Class
     
        Event ErrorOccurred(ByVal ex As Exception)
        Event ScanComplete()
     
        Private _Host_Name As String
        Private _Host_IP As String
     
        Sub New(ByVal Host_Name As String, ByVal Host_IP As String)
            _Host_Name = Host_Name
            _Host_IP = Host_IP
        End Sub
     
        Friend Function DNS_Resolution_Result()
            Dim Result_Resolution As String
            Dim State_Resolution As String
     
            Try
                Result_Resolution = New IPAddress(GetHostByName(_Host_Name).AddressList(0).Address).ToString
            Catch ex As Exception
                Result_Resolution = ""
            End Try
     
            If _Host_Name = "" Then
                State_Resolution = "Not Possible"
            End If
            If Result_Resolution <> "" And Result_Resolution = _Host_IP Then
                State_Resolution = "Resolved"
            ElseIf Result_Resolution = "" Then
                State_Resolution = "Not Resolved"
            ElseIf Result_Resolution <> _Host_IP Then
                State_Resolution = "Not Mached"
            End If
     
            Return State_Resolution
        End Function
     
        Friend Function DNS_Reverse_Result()
            Dim Result_Reverse As String
            Dim State_Reverse As String
     
            Try
                Result_Reverse = Resolve(_Host_IP).HostName
            Catch ex As Exception
                Result_Reverse = ""
            End Try
            If _Host_IP = "" Then
                State_Reverse = "Not Possible"
            End If
            If Result_Reverse <> "" And Result_Reverse = _Host_Name Then
                State_Reverse = "Resolved"
            ElseIf Result_Reverse = "" Then
                State_Reverse = "Not Resolved"
            ElseIf Result_Reverse <> _Host_IP Then
                State_Reverse = "Not Mached"
            End If
     
            Return State_Reverse
        End Function
     
    End Class
    En fait j'aimerais lancer chaque ligne du listview ds un nouveau thread.
    Pour le moment j'ai reussi a obtenir que des erreurs du style : cross thread, etc...
    Quelqu'un pourrait il me donner un coup de main?

    Merci d'avance

    Anax

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Une petite recherche de ton message d'erreur dans le forum t'aurait donné pas mal de résultats

    Seul le thread principal peut accéder à l'interface graphique (ou plus exactement, le thread qui l'a créée). Pour y accéder à partir d'un autre thread, il faut passer par un Invoke.

    Dans un cas comme le tien, je pense qu'il faut que tu utilises un ThreadPool dans lequel tu mets en "file d'attente" des tâches à exécuter (avec la méthode QueueUserWorkItem).

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    oki merci
    J'ai fait enormement de recherche, telechargé les exples de MS avec les différents type de thread.
    J'ai compris comment cela passe d'un bout a un autre mais je ne comprends pas comment, en gros, faire en sorte qu'il execute une ou plusieurs actions qui se trouvent ds la fonction.
    Genre : la fonction execute une ou plusieurs actions ds un thread séparé et retourne le resultat comme pourrait le faire une fonction traditionnel.

    J'ai vraiment du mal avec ce concept n'etant pas developpeur à la base

    Mais je vais au moins faire des recherches sur les indices que tu m'as donné

    Merci encore

    Anax

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    Genre : la fonction execute une ou plusieurs actions ds un thread séparé et retourne le resultat comme pourrait le faire une fonction traditionnel.
    Ben c'est pas tout à fait la même approche : puisque la fonction s'exécute de façon asynchrone, tu ne peux pas faire "resultat = fonction()". Il faut que la fonction sache quoi faire quand elle a terminé pour envoyer le résultat là où il est nécessaire. Par exemple, dans ton cas tu pourrais passer en paramètre le ListViewSubItem où il faut afficher le résultat

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    Bonjour et merci de ta réponse

    Alors apres des recherches, j'ai trouver un petit tuto qui est pas mal afin de comprendre les pools.
    Par contre je ne comprends pas pourquoi je devrais passer le ListViewSubItem en paramètre ? Je pensais qu'il faudrait plutôt passer le Host_Name et le Host_IP en paramètre, le thread effectue les actions et retourne les 2 resultats, a savoir l'etat + couleur du forecolor associé (qui ne fonctionne pas ds mon dev mais je dois chercher encore pq)
    Une fois que je recup ces deux valeurs, je l'ecris ds mon listview a partir de mon thread principal.

    Est ce que je comprends mal comment cela fonctionne?

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    Par contre je ne comprends pas pourquoi je devrais passer le ListViewSubItem en paramètre ? Je pensais qu'il faudrait plutôt passer le Host_Name et le Host_IP en paramètre, le thread effectue les actions et retourne les 2 resultats, a savoir l'etat + couleur du forecolor associé (qui ne fonctionne pas ds mon dev mais je dois chercher encore pq)
    Une fois que je recup ces deux valeurs, je l'ecris ds mon listview a partir de mon thread principal.
    Justement, ce que j'essaie de te dire, c'est que là tu ne peux pas directement récupérer le Host_Name et le Host_IP, puisque la fonction ne va pas forcément être exécutée tout de suite. Si tu attends le résultat dans ta boucle, tu perds tout l'intérêt d'utiliser des threads. Mais si tu ne récupères pas directement le résultat, tu perds le lien avec le ListViewItem correspondant... il faut donc passer au thread toutes les infos nécessaires pour exécuter la recherche DNS et afficher le résultat dans l'interface. Le plus simple pour ça est de créer une classe pour englober les paramètres et le résultat.

    Tu pourrais faire un truc comme ça :
    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
    ' classe qui contient les données de traitement
    Class DnsTask
        Public Sub New(hostname As String, ip As String, lvi As ListViewItem)
            Me.Host_Name = hostname
            Me.Host_IP = ip
            Me.ResultLvi = lvi
        End Sub
     
        Public Host_Name As String
        Public Host_IP As String
     
        Public ResultLvi As ListViewItem
     
        Public DnsResult As String
        Public ReverseDnsResult As String
    End Class
     
    ...
    ' Sub qui exécute le traitement dans un thread du ThreadPool
    Sub ResolveDNS(param As Object)
         Dim task As DnsTask = CType(param, DnsTask)
         Dim Th_DNS = New Thread_DNS_Class(Host_Name, Host_IP)
         task.DnsResult = Th_DNS.DNS_Resolution_Result()
         task.ReverseDnsResult = Th_DNS.DNS_Reverse_Result()
         Dim dlg As SetResultDelegate = New SetResultDelegate(AddressOf SetResult)
         Me.Invoke(dlg, task)
    End Sub
     
    ' Delegué pour afficher le résultat dans le thread principal via Invoke
    Delegate Sub SetResultDelegate(task As DnsTask)
     
    ' Affichage du résultat (s'exécute dans le thread principal grâce à Invoke)
    Sub SetResult(task As DnsTask)
        task.ResultLvi.SubItems(3).Text = task.DnsResult
        Select Case task.DnsResult
            Case "Resolved"
                task.ResultLvi.SubItems(3).ForeColor = Color.Green
            Case "Not Resolved"
                task.ResultLvi.SubItems(3).ForeColor = Color.Red
            Case Else
        End Select
     
        task.ResultLvi.SubItems(4).Text = task.ReverseDnsResult
        Select Case task.ReverseDnsResult
            Case "Resolved"
                task.ResultLvi.SubItems(4).ForeColor = Color.Green
            Case "Not Resolved"
                task.ResultLvi.SubItems(4).ForeColor = Color.Red
            Case Else
        End Select
     
    End Sub
    Et ta boucle devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
            For Compteur = 0 To (NbL_DNS - 1)
                Dim lvi As ListViewItem = LV_DNS.Items(Compteur)
                Host_Name = lvi.SubItems(1).Text
                Host_IP = lvi.SubItems(2).Text
                Dim task As New DnsTask(Host_Name, Host_IP, lvi)
                ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ResolveDNS), task)
            Next
    Sinon, petite remarque sur ton code actuel : tu appelles 2 fois de suite DNS_Resolution_Result et DNS_Reverse_Result, au lieu de réutiliser le résultat que tu viens de récupérer... donc c'est 2 fois plus long

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    Merci pour ta réponse
    J'essaye un peu de comprendre comment cela fonctionne. J'ai une question par rapport a mes tests.
    Plus de pb pour créer les threads et les mettre en queue. Pas de pb pour lui passer des arguments non plus. Par contre qud je regarde ce qui est apssé c est tjrs la derniere ligne qui se repete et je ne comprends pas pq.

    Je te mets mon code de test :

    Voici la classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Imports System.Threading
    Public Class Thread_DNS_Class
     
        Public Shared Sub test(ByVal Variables() As Object)
            Dim Host_Name As String = CType(Variables(0), String)
            Dim Host_IP As String = CType(Variables(1), String)
            Dim Compteur As String = CType(Variables(2), Integer)
            Console.WriteLine(Compteur & " " & Host_Name & " " & Host_IP & " " & "on Thread n°" & Thread.CurrentThread.ManagedThreadId)
     
        End Sub
    End Class
    et pour la boucle j'utilise (sachant que la boucle est ds une autre class)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
            For Compteur = 0 To (NbL_DNS - 1)
                Variables(0) = LV_DNS.Items(Compteur).SubItems(1).Text 'Host_Name
                Variables(1) = LV_DNS.Items(Compteur).SubItems(2).Text 'Host_IP
                Variables(2) = Compteur
                Console.WriteLine(Variables(2) & " " & Variables(0) & " " & Variables(1))
     
                Dim td As WaitCallback = New WaitCallback(AddressOf Thread_DNS_Class.test)
                ThreadPool.QueueUserWorkItem(td, Variables)
            Next
    Je voudrais juste comprendre pq j'obtient tjrs la meme ligne en sortie.
    J'ai fait un test en passant que compteur. Qud je fais cela, ca fonctionne impec.
    J'aimerais juste comprends car le but est peut etre d'utiliser ce system avec des invoke pour mettre a jour mon listview.
    Par contre je ne sais pas si c'est propre mais bon j'essaye de realisé une feuille de class pour une fonction ds mon dev.

    Merci encore pour tes explications. Elles me permettent de comprendre et d'apprendre.

    Anax

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Le problème est que dans ta boucles, tu utilises toujours le même tableau Variables... Résultat :
    - tous les threads ont les mêmes valeurs de paramètres (compteur, hostname, ip)
    - à chaque passage dans la boucle tu écrases les valeurs précédentes

    Il faut créer un nouveau tableau, unique à chaque itération de la boucle (et donc à chaque thread)

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    je ne pense pas bien comprendre. Ds ma boucle en fin de compte, je cree le tableau et je le passe en queue non? ensuite j arrive a mon next et j ecrase mon tableau pour le repasser ds un nouveau thread.
    Je me trompe quelque part? ou alors j'ai pas encore pigé lol

    Merci pour ton temps, c'est fort appreciable

    Anax

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    je ne pense pas bien comprendre. Ds ma boucle en fin de compte, je cree le tableau et je le passe en queue non? ensuite j arrive a mon next et j ecrase mon tableau pour le repasser ds un nouveau thread.
    Je me trompe quelque part? ou alors j'ai pas encore pigé lol
    Quand tu passes le tableau en paramètre de QueueUserWorkItem, tu passes en fait une référence au tableau, pas une copie. Donc tous les threads pointent vers le même tableau, dans lequel tu écrases les données à chaque itération. Il faut que ce soit un nouveau tableau à chaque fois. Déclare le à l'intérieur de la boucle, ça devrait régler le problème

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    Ok alors si je comprends bien, je cree le tableau et ensuite je passe le tableau complet?
    Car pour moi, j aurais espéré lancer un thread par ligne ds mon listview en gros?
    Bon j essaye de reprendre ton code et de le comprendre.
    Comment puis je faire pour que la 1ere partie tienne dans une classe et que la bouche for soit sur le form principal?

    Merci encore pour ton aide

    Anax

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    Ok alors si je comprends bien, je cree le tableau et ensuite je passe le tableau complet?
    Non, tu passes toujours une référence au tableau. C'est pour ça qu'il faut que ce soit un nouveau tableau à chaque fois, sinon les threads partagent tous le même tableau

    Citation Envoyé par Anaxagore Voir le message
    Car pour moi, j aurais espéré lancer un thread par ligne ds mon listview en gros?
    Ben c'est bien ce que tu fais avec ma méthode...
    (Enfin, pas exactement en fait : en utilisant un ThreadPool, tu exécutes les tâches sur un nombre fini de threads. S'il n'y a pas de thread disponible pour exécuter une tâche, elle est mise en attente jusqu'à ce qu'un thread soit libéré. Mais bon, ça change pas grand chose...)

    [QUOTE=Anaxagore;4104800]Comment puis je faire pour que la 1ere partie tienne dans une classe et que la bouche for soit sur le form principal?/QUOTE]
    C'est à dire ? Tu peux tout mettre dans la Form si tu veux...
    D'ailleurs tu n'es pas obligé d'utiliser une classe comme dans mon exemple, ton approche avec un tableau est valable aussi...

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    D'abord merci a toi de prendre autant de tps pour me repondre cela me permet de travailler à partir de tes commentaires et d'essayer de produire un code clair
    Pour être plus précis :
    1) Est il possible de placer ce bout de ton code :
    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
     
    ' classe qui contient les données de traitement
    Class DnsTask
        Public Sub New(hostname As String, ip As String, lvi As ListViewItem)
            Me.Host_Name = hostname
            Me.Host_IP = ip
            Me.ResultLvi = lvi
        End Sub
     
        Public Host_Name As String
        Public Host_IP As String
     
        Public ResultLvi As ListViewItem
     
        Public DnsResult As String
        Public ReverseDnsResult As String
    End Class
     
    ...
    ' Sub qui exécute le traitement dans un thread du ThreadPool
    Sub ResolveDNS(param As Object)
         Dim task As DnsTask = CType(param, DnsTask)
         Dim Th_DNS = New Thread_DNS_Class(Host_Name, Host_IP)
         task.DnsResult = Th_DNS.DNS_Resolution_Result()
         task.ReverseDnsResult = Th_DNS.DNS_Reverse_Result()
         Dim dlg As SetResultDelegate = New SetResultDelegate(AddressOf SetResult)
         Me.Invoke(dlg, task)
    End Sub
     
    ' Delegué pour afficher le résultat dans le thread principal via Invoke
    Delegate Sub SetResultDelegate(task As DnsTask)
     
    ' Affichage du résultat (s'exécute dans le thread principal grâce à Invoke)
    Sub SetResult(task As DnsTask)
        task.ResultLvi.SubItems(3).Text = task.DnsResult
        Select Case task.DnsResult
            Case "Resolved"
                task.ResultLvi.SubItems(3).ForeColor = Color.Green
            Case "Not Resolved"
                task.ResultLvi.SubItems(3).ForeColor = Color.Red
            Case Else
        End Select
     
        task.ResultLvi.SubItems(4).Text = task.ReverseDnsResult
        Select Case task.ReverseDnsResult
            Case "Resolved"
                task.ResultLvi.SubItems(4).ForeColor = Color.Green
            Case "Not Resolved"
                task.ResultLvi.SubItems(4).ForeColor = Color.Red
            Case Else
        End Select
     
    End Sub
    dans une seule classe qui serait dans une feuille autre que le form principal
    et ensuite placer cette boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    For Compteur = 0 To (NbL_DNS - 1)
                Dim lvi As ListViewItem = LV_DNS.Items(Compteur)
                Host_Name = lvi.SubItems(1).Text
                Host_IP = lvi.SubItems(2).Text
                Dim task As New DnsTask(Host_Name, Host_IP, lvi)
                ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ResolveDNS), task)
            Next
    dans le form principale.
    De ce faite, je placerais uniquement la boucle dans un sub de mon form principal.

    2) Je ne comprends pas cette histoire de tableau. En faisant des tests, si par exple je ne passe que la 2eme valeur de mon tableau (soit Variables(2) dans mon exple précedent), ca marche très bien. Par contre, qud j essaye de passer plus d'une variable, ca passe plus. Et j'ai beau regarder comment batir ce tableau, je ne voit pas comment faire


    Il est vrai que j'aimerais bien approcher les 2 methodes, juste pour ma culture perso et apprendre

    Merci encore pour ta patience (je ne suis pas un dev pro)

    Anax

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    Bon j'ai retravaillé le code que tu m'avais donné
    Donc voici ce que j'obtiens mais pb sur invoke
    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
     
    Imports System.Net
    Imports System.Net.Dns
    Imports System.Threading
     
    Public Class DnsTask
        Private Host_Name As String
        Private Host_IP As String
        Private ResultLvi As ListViewItem
     
        Private DnsResult As String
        Private ReverseDnsResult As String
     
     
        Public Sub New(ByVal hostname As String, ByVal ip As String, ByVal lvi As ListViewItem)
            Host_Name = hostname
            Host_IP = ip
            Me.ResultLvi = lvi
        End Sub
     
        ' Sub qui exécute le traitement dans un thread du ThreadPool
        Friend Sub ResolveDNS(ByVal param As Object)
            Dim task As DnsTask = CType(param, DnsTask)
            'Dim Th_DNS = New Thread_DNS_Class(Host_Name, Host_IP)
            DnsResult = DNS_Resolution_Result()
            ReverseDnsResult = DNS_Reverse_Result()
            Dim dlg As SetResultDelegate = New SetResultDelegate(AddressOf SetResult)
            Main.Invoke(dlg, task)
        End Sub
     
        ' Delegué pour afficher le résultat dans le thread principal via Invoke
        Delegate Sub SetResultDelegate(ByVal task As DnsTask)
     
        ' Affichage du résultat (s'exécute dans le thread principal grâce à Invoke)
        Private Sub SetResult(ByVal task As DnsTask)
            ResultLvi.SubItems(3).Text = DnsResult
            Select Case task.DnsResult
                Case "Resolved"
                    ResultLvi.SubItems(3).ForeColor = Color.Green
                Case "Not Resolved"
                    ResultLvi.SubItems(3).ForeColor = Color.Red
                Case Else
            End Select
     
            ResultLvi.SubItems(4).Text = ReverseDnsResult
            Select Case ReverseDnsResult
                Case "Resolved"
                    ResultLvi.SubItems(4).ForeColor = Color.Green
                Case "Not Resolved"
                    ResultLvi.SubItems(4).ForeColor = Color.Red
                Case Else
            End Select
        End Sub
     
        Private Function DNS_Resolution_Result()
            Dim Result_Resolution As String
            Dim State_Resolution As String
     
            Try
                Result_Resolution = New IPAddress(GetHostByName(Host_Name).AddressList(0).Address).ToString
            Catch ex As Exception
                Result_Resolution = ""
            End Try
     
            If Host_Name = "" Then
                State_Resolution = "Not Possible"
            End If
            If Result_Resolution <> "" And Result_Resolution = Host_IP Then
                State_Resolution = "Resolved"
            ElseIf Result_Resolution = "" Then
                State_Resolution = "Not Resolved"
            ElseIf Result_Resolution <> Host_IP Then
                State_Resolution = "Not Mached"
            End If
     
            Return State_Resolution
        End Function
        Private Function DNS_Reverse_Result()
            Dim Result_Reverse As String
            Dim State_Reverse As String
     
            Try
                Result_Reverse = Resolve(Host_IP).HostName
            Catch ex As Exception
                Result_Reverse = ""
            End Try
            If Host_IP = "" Then
                State_Reverse = "Not Possible"
            End If
            If Result_Reverse <> "" And Result_Reverse = Host_Name Then
                State_Reverse = "Resolved"
            ElseIf Result_Reverse = "" Then
                State_Reverse = "Not Resolved"
            ElseIf Result_Reverse <> Host_IP Then
                State_Reverse = "Not Mached"
            End If
     
            Return State_Reverse
        End Function
    End Class
    et pour la boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    For Compteur = 0 To (NbL_DNS - 1)
                Dim lvi As ListViewItem = LV_DNS.Items(Compteur)
                Host_Name = lvi.SubItems(1).Text
                Host_IP = lvi.SubItems(2).Text
                Dim task As New DnsTask(Host_Name, Host_IP, lvi)
                ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf task.ResolveDNS), task)
            Next
    et l erreur sur invoke est le suivant : Invoke or BeginInvoke cannot be called on a control until the window handle has been created.

    J'ai du me planter quelque part

    Anax

  15. #15
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    1) Est il possible de placer ce bout de ton code dans une seule classe qui serait dans une feuille autre que le form principal
    ...
    et ensuite placer cette boucle dans le form principale.
    De ce faite, je placerais uniquement la boucle dans un sub de mon form principal.
    Oui, mais dans ce cas il faut que tu passes à cette classe une référence vers la Form, pour pouvoir appeler Invoke dessus

    Citation Envoyé par Anaxagore Voir le message
    2) Je ne comprends pas cette histoire de tableau. En faisant des tests, si par exple je ne passe que la 2eme valeur de mon tableau (soit Variables(2) dans mon exple précedent), ca marche très bien. Par contre, qud j essaye de passer plus d'une variable, ca passe plus. Et j'ai beau regarder comment batir ce tableau, je ne voit pas comment faire
    J'ai déjà essayé 2 ou 3 fois de te l'expliquer, et je ne vois plus comment le formuler autrement
    En fait je pense que tu n'as pas bien compris le principe des types références et des types valeurs... je te suggère d'aller voir le cours de VB.NET de Philippe Lasserre (ici) pour t'éclaircir sur ce point

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    Bon concernant le tableau, j'ai repris le tuto que j'avais deja parcouru en me lancant et apres de multiples tests, je comprends ce que j'envoie maintenant.
    Je sais je suis un peu, bcp lent a la comprenure

    par contre pour :
    Oui, mais dans ce cas il faut que tu passes à cette classe une référence vers la Form, pour pouvoir appeler Invoke dessus
    Je comprends pas ce que tu veux dire

    Anax

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    Je comprends pas ce que tu veux dire
    Ben dans ma méthode ResolveDns, il y a un "Me.Invoke". Me fait référence à la classe courante (en l'occurence la Form), donc si tu mets ça dans une autre classe, il faut remplacer Me par une référence vers la Form. Mais en fait je viens de voir que tu as déjà remplacé Me par Main (je suppose que c'est le nom de ta Form), donc tu peux oublier ça...

    Juste une petite parenthèse :
    En VB.NET, tu peux utiliser le nom d'une Form (le nom de la classe, Main en l'occurrence) comme si c'était une variable : c'est un truc complètement spécifique à VB.NET, et d'un point de vue programmation orientée objet, c'est une aberration... Je pense que Microsoft a gardé ça pour faciliter la migration depuis VB6, mais normalement tu devrais utiliser une variable de type Main, et non directement Main.

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    Ok alors j avais bien compris ce que ca signifié en ayant regarder quelques tuto. Cependant j'ai tjrs l'erreur et je ne comprends pas pq.
    Effectivement Main = mon main form ds lequel j'ai mon listview

    Je suis content d'avoir compris une petite chose lol
    Je suis même en train de me lancer sur la modification d'une autres partie de mon code sur ce travail

    Pour en revenir a mon erreur, aurais tu un indice pour resoudre cette erreur ?

    Anax

  19. #19
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par Anaxagore Voir le message
    et l erreur sur invoke est le suivant : Invoke or BeginInvoke cannot be called on a control until the window handle has been created.
    Arf, j'avais raté ce post... tu as du l'envoyer pendant que j'écrivais la réponse au précédent

    A quel moment tu exécutes la boucle ? D'après le message d'erreur, je dirais que l'exécutes avant que la Form ne soit affichée, et le handle de la Form n'est donc pas encore créé. Pour régler ça, tu peux appeler la méthode CreateControl juste avant, pour forcer la création du handle

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 127
    Points : 61
    Points
    61
    Par défaut
    ALors si je comprends bien, je ne pense pas que cela soit cela.
    Voici ce que je fais :

    1) Main form est loader au lancement avec le listview vide
    2) Je clique sur un bouton pour remplir le listview a partir d'un fichier
    3) Je clique sur un bouton pour lancer le traitement qui modifie une cellule du listview apres traitement

    cela serait il du fait que je modifie la cellule du listview ?

    Anax

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

Discussions similaires

  1. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  2. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28
  3. Programmer des threads
    Par haypo dans le forum C
    Réponses: 6
    Dernier message: 02/07/2002, 13h53
  4. Réponses: 5
    Dernier message: 12/06/2002, 15h12
  5. [Kylix] Pb de Thread !!
    Par Anonymous dans le forum EDI
    Réponses: 1
    Dernier message: 25/04/2002, 13h53

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