Listbox veut pas se remplir ds Thread (vb.net)

Résolu
nerone21
Messages postés
108
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
5 mai 2011
- 16 juin 2007 à 18:10
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
- 17 juin 2007 à 18:19
Bonjour à tous les serials codeur, j'ai un petit souçis avec un mechant thread ou une mechante form... je précise je suis un débutant, alors un peu d'indulgence SVP ^^...

Voila mon code: (partie problématique en rose)

Public Class Form1
    Inherits System.Windows.Forms.Form

'.......................... code de la forme ..............................'
:....
:....
:....

'...........................code de la thread.............................'

#Region "Thread Ping"

    'premier Thread de Ping
    Private _threadPing1 As Thread
    ' Evénement pour signaler la fin des threads de Ping
    Private _endThreadPingEvent As New ManualResetEvent(False)

    'Classe ThreadPing
    Private Class ThreadPing

        'form parente
        Private _frm As Form1
        'temporisation
        Private _tempo As Integer

        Private _ipthread As String() = New String(131072) {}

        Private _SetIP As Single

        'Constructeur. frm et tempo sont les paramètres de notre Thread
        Public Sub New(ByVal frm As Form1, ByVal tempo As Integer, ByVal ipthread As String(), ByVal setip As Single)
            _frm = frm
            _tempo = tempo
            _ipthread = ipthread
            _SetIP = setip
        End Sub

        'Fonction du Thread
        Public Sub ThrFunc()
            Try
                _frm.Ping(_ipthread, _tempo, _SetIP)
            Catch ex As Exception
                Debug.WriteLine(ex.ToString())
            End Try
        End Sub

    End Class

    'Démarrage du thread
    Private Sub StartThread(ByVal ip As String(), ByVal Setip As Single)

        Dim myThreadObj As New ThreadPing(Me, 1000, ip, Setip)
        _threadPing1 = New Thread(AddressOf myThreadObj.ThrFunc)
        _threadPing1.Name = "ThreadPing"
        _threadPing1.Start()

    End Sub

Partie problématique...:

    Function Ping(ByVal ip As String(), ByVal tempo As Integer, ByVal PosTabIp As Integer) As Boolean
        While Not _endThreadPingEvent.WaitOne(tempo, False)
            For index As Integer = 0 To PosTabIp
                Dim siteResponds As Boolean = False                If (siteResponds My.Computer.Network.Ping(ip(index))) False Then
                    Me.ListBox1.Items.Add(ip)
                    Me.Update()
                Else
                    Me.ListBox2.Items.Add(ip)       //lorsque la thread arrive ici elle va direct sur "Catch ex As Exception" et je sort de la fonction...
                    Me.Update()
                End If
            Next
        End While
    End Function
#End Region
End Class

Voilà, je sais vraiment pas le pourquoi ca fait ca . en fait je veut ke quand le ping de l'adresse ip est true qu'il aille s'inscrire ds une listbox de la form et sinon ds l'autre listbox de la même forme ...

Ah oui et la variable TEMPO, je sais pas du tout a koi elle sert, G trouvé le code de la thread sur un forum... donc en même temps si vous connaissez son utilité, j'aimerais savoir.

Donc si vraiment quelqu'un pouvait m'aider ce serait fort agréable pakeu je péte les plombs de pas comprendre...

Merci a vooooous... bonne continuation

27 réponses

Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
17 juin 2007 à 10:10
Oups, je me suis trompé dans la déclaration du Delegate et en plus c'est mal foutu, je te le remets :

'Dans la Thread fille
Dim r(1) As Object
r(0) = ListBox1
r(1) = ip
Invoke(New delAddItem(AddressOf AddItem), r)


Delegate Sub delAddItem(ByVal lb As ListBox, ByVal item As Object)
'Appelé par le thread principal...
Sub AddItem(ByVal lb As ListBox, ByVal item As Object)
   lb.Items.Add(item)
End Sub





<hr width="100%" size="2" />


Julien.
3
Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
17 juin 2007 à 15:00
Alors, r(0) est déclaré, quand je déclare r(1) as object, ca doit se lire déclaration d'un array d'objets de 2 (1 + 1 comme c'est basé en 0) éléments dont les index vont de 0 à 1. Donc r(0) est déclaré et r(1) est déclaré.
Alors une implémentation possible de mon code serait :

    Function Ping(ByVal ip As String(), ByVal tempo As Integer, ByVal PosTabIp As Integer) As Boolean
        While Not _endThreadPingEvent.WaitOne(tempo, False)
            For index As Integer = 0 To PosTabIp
                Dim siteResponds As Boolean = False
                Dim args(1) as Object                If (siteResponds My.Computer.Network.Ping(ip(index))) False Then
                    args(0) = Me.ListBox1
                    args(1) = ip
                    ListBox1.Invoke(New delAddItem(AddressOf AddItem), r)
                    <strike>Me.ListBox1.Items.Add(ip)</strike>
                    Me.Update()
                Else
                    args(0) = Me.ListBox2
                    args(1) = ip
                    ListBox2.Invoke(New delAddItem(AddressOf AddItem), r)
                    <strike>Me.ListBox2.Items.Add(ip)</strike> 
                    Me.Update()
                End If
            Next
        End While
    End Function

(A mon avis le Me.Update() pourra te causer le même problème, si oui, applique la même technique...)

Et alors tu ajoutes ces déclarations :

Delegate Sub delAddItem(ByVal lb As ListBox, ByVal item As Object)

Sub AddItem(ByVal lb As ListBox, ByVal item As Object)
   lb.Items.Add(item)
End Sub

<hr width="100%" size="2" />Julien.
3
Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
17 juin 2007 à 18:03
Il passe dans le catch, mais c'est pas la même erreur si ? Dis un peu l'erreur qui est levée ?
Sinon s'il met system.string[], à mon avis ca veut dire que contrairement à ce que je pensais, il l'a enregistré en tableau de string et non en simple string va savoir pourquoi...
Dans ce cas, le cast devient
lb.Items.Add(CType(item, string())(0))

<hr width="100%" size="2" />Julien.
3
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
2
16 juin 2007 à 18:27
en gros : on peut jamais acceder à l'interface utilisateur depuis un thread

(tout autre thread différent du thread constructeur ne peut pas acceder en ecriture : il peut à peine avoir la lecture seule des valeurs etc)

j'espère avoir été clair lol
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
2
16 juin 2007 à 18:28
=> pour corriger : met tout dans le même thread que l'interface
0
nerone21
Messages postés
108
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
5 mai 2011

16 juin 2007 à 18:33
alors d'accord mais j'ai pas tout compris malheureusement pour la solution... qu'es ce que veut dire tout mettre "ds le même thread que l'interface???"... un exemple STP ou alors la correction de mon code pour mettre les truc a leur place et correctement....

Merci d'avance.
0
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
2
16 juin 2007 à 18:35
met aucun thread dans ton code ... (c'est du VB 2003 ou 2002 j'ai du mal avec ça dsl)
0
nerone21
Messages postés
108
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
5 mai 2011

16 juin 2007 à 18:38
Oui mais malheureusement ca va me bloquer ma fenetre...

donc... heeeeeeeelp
0
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
2
16 juin 2007 à 18:44
en ajoutant Application.DoEvents en plein milieu ça peut aider les choses (pas sûr)

Function Ping(ByVal ip As String(), ByVal tempo As Integer, ByVal PosTabIp As Integer) As Boolean
        While Not _endThreadPingEvent.WaitOne(tempo, False)
            For index As Integer = 0 To PosTabIp
                Dim siteResponds As Boolean = False                If (siteResponds My.Computer.Network.Ping(ip(index))) False Then
                    Me.ListBox1.Items.Add(ip)
                    Me.Update()
                Else
                    Me.ListBox2.Items.Add(ip)       //lorsque la thread arrive ici elle va direct sur "Catch ex As Exception" et je sort de la fonction...

                    Me.Update()
                End If
Application.DoEvents() ' <=======
            Next
        End While
    End Function
0
Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
16 juin 2007 à 21:51
Salut
C'est normal c'est une protection des controles, comme dit allthew les controles ne peuvent êtres accèder que part le thread les ayant créé. Pour enlever cette protection, fais simplement Control.Checkforillegalcrossthread = false au début de ton prog et c'est réglé...

<hr size="2" width="100%" />Julien.
0
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
2
17 juin 2007 à 09:52
Julien237 : en VB 2005 il est très déconseillé de faire ça parce que ça peut créer des bugs incompréhensibles ... (en 2002 et 2003 idem je pense)

donc soit t'enlèves la protection (à tes risques et périls) ou trouver 1 autre moyen (mais lequel ?)

++
0
Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
17 juin 2007 à 10:07
Ah bon ? J'ai jamais eu de problèmes avec ça et tous les tutos que j'ai vu sur le multi-threading font de cette manière...
Alors voilà une autre manière de faire, tu peux utiliser Invoke. Dans la thread fille, à la place des Me.ListboxX.Item.Add(ip), tu mets

Dim r(1)
As
Objectr(0) = ListBox1

r(1) = ip

Invoke(

New delAddItem(
AddressOf AddItem), r)

Et tu déclare dans ton form
Delegate

Sub delAddItem(
ByVal x
As
Object)

Sub AddItem(
ByVal lb
As ListBox,
ByVal item
As
Object)lb.Items.Add(item)

End
SubAinsi l'accès à la listbox sera bien effectué par le thread l'ayant créé...

<hr width="100%" size="2" />Julien.
0
allthew3
Messages postés
551
Date d'inscription
samedi 8 janvier 2005
Statut
Membre
Dernière intervention
12 avril 2008
2
17 juin 2007 à 10:33
ah un délégué c'est deja plus propre

++

PS : julien237 tu m'as fait pensé que moi aussi je peux utiliser les délégués dans mes applications (j'y pense jamais et je me débrouille autrement ...) : merci
0
OneHacker
Messages postés
1447
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
23 septembre 2007
2
17 juin 2007 à 14:17
Autremebt comme on m'avait conseille pour éviter l'interaction entre 2 threads différent ce sont les délégués.

Redman
0
OneHacker
Messages postés
1447
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
23 septembre 2007
2
17 juin 2007 à 14:20
Oops j'avais pas lu la page 2, désolé. Par contre dans ton code Julien, on ne pe pas instancier la valeur d'une collection "dim r(1) As Object" mais c'est plutôt la collection que tu dois instancier.

Redman
0
Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
17 juin 2007 à 14:21
Heu moi je vois pas le problème ^^...

<hr width="100%" size="2" />Julien.
0
nerone21
Messages postés
108
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
5 mai 2011

17 juin 2007 à 14:37
D'accord merci julien mais le code ke tu m'as donné je met tout ca où?

si tu peu reprendre mon code initiale (page 1) et me mettre tout ca a sa place ca m'aiderait ^^

et ossi pkoi r(0) n'est pas déclaré??

merci par avance...
0
nerone21
Messages postés
108
Date d'inscription
vendredi 4 mars 2005
Statut
Membre
Dernière intervention
5 mai 2011

17 juin 2007 à 15:51
alors ca marche MAIS... ^^

ds mes listbox n'apparait pas l'"ip" mais "system.string[]" donc si tu peut me corriger ca vite fait bien fait je t'en remerci...
0
Julien237
Messages postés
883
Date d'inscription
vendredi 3 novembre 2000
Statut
Membre
Dernière intervention
3 mars 2009
7
17 juin 2007 à 16:17
Ha oui, c'est une bêtise ^^
A la place de lb.Items.Add(item), mets lb.Items.Add(CType(item, String))
Et je pense que ca devrait aller...

<hr width="100%" size="2" />Julien.
0
OneHacker
Messages postés
1447
Date d'inscription
jeudi 2 novembre 2000
Statut
Membre
Dernière intervention
23 septembre 2007
2
17 juin 2007 à 16:23
Ah non je suis bête 1 c'est la valeur pour instancier le tableau, je l'avais compris différement ^^

Redman
0