nerone21
Messages postés108Date d'inscriptionvendredi 4 mars 2005StatutMembreDernière intervention 5 mai 2011
-
16 juin 2007 à 18:10
allthew3
Messages postés551Date d'inscriptionsamedi 8 janvier 2005StatutMembreDernière intervention12 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...
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 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
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 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
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 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))
nerone21
Messages postés108Date d'inscriptionvendredi 4 mars 2005StatutMembreDerniè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....
allthew3
Messages postés551Date d'inscriptionsamedi 8 janvier 2005StatutMembreDernière intervention12 avril 20082 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
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 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é...
Julien237
Messages postés883Date d'inscriptionvendredi 3 novembre 2000StatutMembreDernière intervention 3 mars 20097 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éé...
allthew3
Messages postés551Date d'inscriptionsamedi 8 janvier 2005StatutMembreDernière intervention12 avril 20082 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
OneHacker
Messages postés1447Date d'inscriptionjeudi 2 novembre 2000StatutMembreDernière intervention23 septembre 20072 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.