Visual Basic.NET - Error al mostrar datos en datagridview desde multiples hilos

 
Vista:
sin imagen de perfil

Error al mostrar datos en datagridview desde multiples hilos

Publicado por Gabino (3 intervenciones) el 03/10/2016 02:13:43
Tengo un sistema que escanea la red ip por ip sacando informacion de cada dispositivo como ser la mac y el serial etc. El programa funciona correctamente si escaneo una ip a la vez pero tarda bastante tiempo por lo que decidi implementar el proceso con multiples hilos.
Parece funcionar bastante bien ya que hace el proceso correcto pero cuando muestro los datos en un datagridview me muestra un error y no tengo la mas minimia idea de como solucionarlo, ya probe controlando la cantidad de hilos que creo mientras el programa esta funcionando y aun asi me da el error.
Adjunto imagen del error que me arroja al usar try..catch
error1

Ese error detiene completamente mi aplicacion.
Estas son las dos funciones principales de mi aplicacion:

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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
Private Sub escanear(ip As IpAddress)
    Dim Datos As New fPruebas
    Dim oids As New vOids
 
    Dim gupSpeed = ""
    Dim gdownSpeed = ""
    Dim gmodelo = ""
    Dim gmac = ""
    Dim gserial = ""
    Dim gssid = ""
    Dim gpasswifi = ""
 
    Dim funcDatos As New fDatos
    Dim salida As String
    Dim funcFunciones As New ffunciones
    Try
        salida = Datos.extraerDatos(ip.ToString, oids.modelo)
        If salida = "" Then
            salida = Datos.extraerDatos(ip.ToString, oids.modelo2)
        ElseIf salida = "" Then
            salida = Datos.extraerDatos(ip.ToString, oids.modelo3)
        Else
            If salida = "" Then
            End If
        End If
        salida = funcFunciones.eliminarEspacios(salida)
        gmodelo = salida
        'obtener serial
        salida = Datos.extraerDatos(ip.ToString, oids.serial)
        salida = funcFunciones.eliminarEspacios(salida)
        gserial = salida
        'obtener mac
        salida = Datos.extraerDatos(ip.ToString, oids.mac)
        salida = funcFunciones.eliminarEspacios(salida)
        gmac = salida
        'obtener subida y bajada
        salida = Datos.extraerDatos(ip.ToString, oids.velocidad)
        downUp(salida)
        If gmodelo Is Nothing Then
            'ssid
            salida = Datos.extraerDatos(ip.ToString, oids.ssid)
            gssid = salida
            'obtener passWifi
            salida = Datos.extraerDatos(ip.ToString, oids.passWifi)
            gpasswifi = salida
        Else
            If gmodelo.ToString.Contains("SBG941") Or gmodelo.ToString.Contains("SBG901") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidSBG)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiSBG)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("TC7300") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidTechnicolor)
                gssid = salida
                'passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiTechnicolor)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("CG3000D") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidNetgear)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiNetgear)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("HitronBroadbandCableModem") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidHiltron)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiHiltron)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("SMCNetworksCableModemRouter") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidSMC)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiSMC)
                gpasswifi = salida
            Else
                salida = Datos.extraerDatos(ip.ToString, oids.ssid)
                gssid = salida
                salida = Datos.extraerDatos(ip.ToString, oids.passWifi)
                gpasswifi = salida
            End If
        End If
        'Escribir en el datarow
        'MsgBox(Convert.ToString(ip) + " " + gmodelo + " " + gmac + " " + gserial + " " + "Descarga" + " " + "Subida" + " " + gssid + " " + gpasswifi)
        System.Threading.Thread.Sleep(1000)
        dataSalida.Rows.Add(Convert.ToString(ip), gmodelo, gmac, gserial, "Descarga", "Subida", gssid, gpasswifi)
        'ListBox1.Items.Add(Convert.ToString(ip) & "||" & gmodelo & "||" & gmac & "||" & gserial & "||" & gdownSpeed & "||" & gupSpeed & "||" & gssid & "||" & gpasswifi)
        CantHilos = CantHilos - 1
        Application.DoEvents()
    Catch ex As Exception
        MsgBox(ex.Message & "Principal")
    End Try
End Sub
 
Private Sub enviarIp()
    Dim ipInicial As String = txtIpInicial.Text
    Dim ipFinal As String = txtIpFinal.Text
    Dim ipActual As New IpAddress(txtIpInicial.Text)
    Try
        While txtIpInicial.Text.ToString <> txtIpFinal.Text.ToString
            If CantHilos < 100 Then
                Dim hilo As Threading.Thread
                hilo = New Threading.Thread(AddressOf escanear)
                hilo.Start(ipActual)
                CantHilos += 1
                ipActual = ipActual.Increment(1)
                txtIpInicial.Text = ipActual.ToString
                Application.DoEvents()
            Else
                System.Threading.Thread.Sleep(1000)
            End If
        End While
        btnIniciar.Text = "Iniciar"
        btnDetener.Enabled = False
        btnIniciar.Enabled = True
        MsgBox("Proceso Terminado")
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

Existe otra funcion que es la que obtiene los datos de los dispositivos conectados a la red pero solo devuelve cadenas.

Les agradecere su ayuda.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 481
Bronce
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Error al mostrar datos en datagridview desde multiples hilos

Publicado por Miguel (476 intervenciones) el 03/10/2016 16:37:18
Hola,

Bien, pues según los mensajes son diferentes errores; muestra el error completo en el mensaje (con ex.ToString()) para ver dónde ha fallado.

También que yo sepa no se pueden manipular controles desde un Thread, así que es posible que la falla sea donde agregas los datos al DataGridView.

Yo te recomiendo que uses BackgroundWorker's en lugar de Thread's. Créalos en tiempo de ejecución junto con sus eventos (DoWork, RunWorkerCompleted). En el evento DoWork realizas el proceso y en el evento RunWorkerCompleted revisas si ha finalizado correctamente e insertas los datos al control; ve pasando los datos en los parámetros de los eventos (UserState creo).


Saludos,
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Error al mostrar datos en datagridview desde multiples hilos

Publicado por Gabino (3 intervenciones) el 04/10/2016 08:28:13
Estoy tratando de comprender los backgroundWorkers pero no encuentro informacion para crear los backgroundWorkers en tiempo de ejecucion. Encontre como hacerlo en c# pero no me trabaja para vb.net y no se porque. La informacion para crearlos en tiempo de ejecucion en vb.net es bien escasa.
Muchas gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Error al mostrar datos en datagridview desde multiples hilos

Publicado por Nacho (56 intervenciones) el 04/10/2016 14:39:45
Puedes seguir usando la clase thread pero bien, no de cualquier manera. Lo que no permite .net es acceder a un control creado desde un thread desde otro distinto a pelo. Hay que hacerlo así https://msdn.microsoft.com/es-es/library/ms171728(v=vs.110).aspx
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil

Error al mostrar datos en datagridview desde multiples hilos

Publicado por Gabino (3 intervenciones) el 05/10/2016 01:35:35
Muchas gracias a nacho por su ayuda, ya habia intentado usando delegados pero por alguna razon no me habia funcionado.
Utilice como apoyo el hilo que comentaste pude resolver el problema.

El codigo resultante es el siguiente:

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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
Private Sub escanear(ip As IpAddress)
    Dim Datos As New fPruebas
    Dim oids As New vOids
    Dim gupSpeed = ""
    Dim gdownSpeed = ""
    Dim gmodelo = ""
    Dim gmac = ""
    Dim gserial = ""
    Dim gssid = ""
    Dim gpasswifi = ""
    Dim funcDatos As New fDatos
    Dim salida As String
    Dim funcFunciones As New ffunciones
    Try
        salida = Datos.extraerDatos(ip.ToString, oids.modelo)
        If salida = "" Then
            salida = Datos.extraerDatos(ip.ToString, oids.modelo2)
        ElseIf salida = "" Then
            salida = Datos.extraerDatos(ip.ToString, oids.modelo3)
        Else
            If salida = "" Then
            End If
        End If
        salida = funcFunciones.eliminarEspacios(salida)
        gmodelo = salida
        'obtener serial
        salida = Datos.extraerDatos(ip.ToString, oids.serial)
        salida = funcFunciones.eliminarEspacios(salida)
        gserial = salida
        'obtener mac
        salida = Datos.extraerDatos(ip.ToString, oids.mac)
        salida = funcFunciones.eliminarEspacios(salida)
        gmac = salida
        'obtener subida y bajada
        salida = Datos.extraerVelocidad(ip.ToString, oids.velocidad)
        MsgBox(salida)
        downUp(salida)
        If gmodelo Is Nothing Then
            'ssid
            salida = Datos.extraerDatos(ip.ToString, oids.ssid)
            gssid = salida
 
            'obtener passWifi
            salida = Datos.extraerDatos(ip.ToString, oids.passWifi)
            gpasswifi = salida
        Else
            If gmodelo.ToString.Contains("SBG941") Or gmodelo.ToString.Contains("SBG901") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidSBG)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiSBG)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("TC7300") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidTechnicolor)
                gssid = salida
                'passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiTechnicolor)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("CG3000D") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidNetgear)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiNetgear)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("HitronBroadbandCableModem") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidHiltron)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiHiltron)
                gpasswifi = salida
            ElseIf gmodelo.ToString.Contains("SMCNetworksCableModemRouter") Then
                'ssid
                salida = Datos.extraerDatos(ip.ToString, ssidSMC)
                gssid = salida
                'obtener passWifi
                salida = Datos.extraerDatos(ip.ToString, passWifiSMC)
                gpasswifi = salida
            Else
                salida = Datos.extraerDatos(ip.ToString, oids.ssid)
                gssid = salida
                salida = Datos.extraerDatos(ip.ToString, oids.passWifi)
                gpasswifi = salida
            End If
        End If
 
        SetDatagrid(Convert.ToString(ip), gmodelo, gmac, gserial, gdownSpeed, gupSpeed, gssid, gpasswifi)
 
        CantHilos = CantHilos - 1
        Application.DoEvents()
    Catch ex As ThreadAbortException
        MsgBox(ex.Message)
        Thread.ResetAbort()
    Catch ex As Exception
        MsgBox(ex.Message & "Principal")
    End Try
End Sub
 
Private Sub enviarIp()
    Dim ipInicial As String = txtIpInicial.Text
    Dim ipFinal As String = txtIpFinal.Text
    Dim ipActual As New IpAddress(txtIpInicial.Text)
    Try
        While txtIpInicial.Text.ToString <> txtIpFinal.Text.ToString
            If CantHilos < 100 Then
                Dim hilo As Threading.Thread
                hilo = New Threading.Thread(AddressOf escanear)
                hilo.Start(ipActual)
                CantHilos += 1
                ipActual = ipActual.Increment(1)
                txtIpInicial.Text = ipActual.ToString
                Application.DoEvents()
            Else
                System.Threading.Thread.Sleep(1000)
            End If
        End While
        btnIniciar.Text = "Iniciar"
        btnDetener.Enabled = False
        btnIniciar.Enabled = True
        MsgBox("Proceso Terminado")
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub
 
 
Delegate Sub Setdata(ByVal ip As String, ByVal modelo As String, ByVal mac As String, ByVal serial As String, _
                             ByVal DownSpeed As String, ByVal UpSpeed As String, ByVal ssid As String, ByVal password As String)
 
Private Sub SetDatagrid(ByVal ip As String, ByVal modelo As String, ByVal mac As String, ByVal serial As String, _
                        ByVal downSpeed As String, ByVal upSpeed As String, ByVal ssid As String, ByVal password As String)
    If Me.dataSalida.InvokeRequired Then
        Dim d As New Setdata(AddressOf SetDatagrid)
        Me.Invoke(d, New Object() {[ip], [modelo], [mac], [serial], [downSpeed], [upSpeed], [ssid], [password]})
    Else
        Me.dataSalida.Rows.Add(ip, modelo, mac, serial, downSpeed, upSpeed, ssid, password)
    End If
End Sub

Al final la declaracion del delegado con todos sus parametros y la funcion para colocar los datos al datagridview.

Muchas gracias otra vez
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar