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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 129
    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 : 44
    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
    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 confirmé
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 129
    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 : 44
    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
    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 confirmé
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    129
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2003
    Messages : 129
    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 : 44
    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
    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

+ Répondre à la discussion
Cette discussion est résolue.

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