Problema con Thread en vb.net 2005
SOLUCIÓN PROPUESTA
Estimado Javier:
Me encanta el cuestionamiento que haces en tu primera pregunta, ya que efectivamente es un error simplemente quitarle al control que haga la revisión de llamadas cruzadas entre hilos de manera ilegal. Yo particularmente no lo haría y mas bien implementaría un par de cambios a tu código que permitirían realizar la llamada de manera segura.
Pero antes déjame comentarte que es lo que esta pasando. Cuando utilizas mas de un hilo a la vez y estos manipulan el estado de un control es probable que se presente una inconsistencia en el estado del control provocado porque el mismo control puede ser modificado por los dos hilos al mismo tiempo.
Y es por eso que a partir del framework 2.0 cuando tu estas ejecutando tu aplicación en el debbuger y un hilo diferente al que creo el control intenta llamar al mismo el framework te avisa que se esta haciendo la llamada de manera no segura enviándote un error del tipo InvalidOperationException con el fin de que puedas identificarlo para corregirlo y que no te suceda con la aplicación ya trabajando en tiempo de ejecución.
Para corregir esto lo que tienes que hacer es verificar si la llamada que esta tratando de realizar la operación sobre el control es ejecutada desde el mismo hilo que lo creo y en caso contrario deberás hacer una llamada asíncrona por medio de un delegado invocando al mismo por medio del hilo del formulario que creo el objeto.
Pero como todo esto que te acabo de comentar suena un poco complicado voy a aplicar la solución a tu código para que lo puedas ver mas claramente.
CodigoProblemaConThread.txt
Imports System.Threading
Public Class Form1
'Se agrego un delegado que sera el que se
'encarge de la llamada asíncrona que agregue
'el ítem a la lista
Delegate Sub AddItemCallBack _
(ByVal Item As Integer)
Private Sub Button1_Click _
(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
Dim obj_multi As New Thread _
(AddressOf llenar)
obj_multi.Start()
End Sub
Private Sub llenar()
Dim cont As Integer
For cont = 0 To 100
'En lugar de llamar directamente al
'ListBox vamos a ejecutar
'un método de la clase llamado
'AddItemToLista
Me.AddItemToList(cont)
'ListBox1.Items.Add(cont)
Next
End Sub
'Este método demuestra un patrón para realizar
'llamadas seguras a hilos
'en un control Windows Forms.
'Si el hilo que hace la llamada es diferente
'que el hilo que creo el control
'ListBox, entonces el método crea un
'AddItemCallBack y lo manda llamar desde
'el mismo de manera asíncrona utilizando en
'método invoke.
'Si el hilo es el mismo que el que creo el
'control ListBox, entonces el Ítem
' es agregado directamente
Public Sub AddItemToList(ByVal Item As Integer)
If Me.ListBox1.InvokeRequired Then
Dim d As New AddItemCallBack _
(AddressOf AddItemToList)
Me.Invoke(d, New Object() {Item})
Else
ListBox1.Items.Add(Item)
End If
End Sub
End Class
Espero sinceramente que la información te sea de utilidad.
Atentamente,
Raúl Guerrero
http://www.superneurona.com
MENSAJE ORIGINAL
"Javier Muñoz" wrote:
> Tengo el siguiente problema, que aparece en un post anterior, pero que no me da una solucion satisfactoria.
> tengo el siguiente codigo demo:
>
>
> Imports System.Threading
>
> Public Class Form1
>
>
>
> Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
>
> Dim obj_multi As New Thread(AddressOf llenar)
>
> obj_multi.Start()
>
> End Sub
>
>
>
>
>
> Private Sub llenar()
>
> Dim cont As Integer
>
> For cont = 0 To 100
>
> ListBox1.Items.Add(cont)
>
> Next
>
> End Sub
>
>
>
> End Class
>
> y me da el siguiente error:
>
> Message="Operación no válida a través de subprocesos: Se tuvo acceso al control 'ListBox1' desde un subproceso distinto a aquel en que lo creó."
>
> en el post anterior se desia que se podia remediar colocando siguiente valor en el LOAD del formulario
> Control.CheckForIllegalCrossThreadCalls = False
> pero mi duda y preocupacion es la siguiente.
> 1.- Si el Frameworks 2.0 trabaja asi, tiene que ser por alguna razon, y si coloco este codigo el sistema corre el riesgo de crear un fallo, o me equivoca ?
> 2.- Como tendria que hacerlo para seguir las reglas de frameworks 2.0, para realizar esta operacion ??
> desde ya, muchas gracias por su ayuda
REFERENCIA AL GRUPO DE NOTICIAS:
http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?dg=microsoft.public.es.dotnet.vb&mid=b1332745-8dfc-493d-b7e8-6347613144ca


10 Comments:
Y como puedo accesar las propiedades de un ContextMenu (especificamente quiero cambiar la propiedad Enabled) si no tiene la propiedad de InvokeRequired?
He revisado el control contextMenuStrip y si contiene dicha propiedad.
Me podrías indicar que lenguaje y que versión de .NET estas utilizando.
Saludos.
Hola, he implementado en mi codigo algo como lo que comentas, pero existe algo que me esta pasando en la aplicación.
El motivo por el que necesito el hilo nuevo es porque quiero que el usuario siga trabajando con la aplicación mientras se copian unos datos de una grid. pero con la implementación que mencionas se ejecuta bien la copia pero se bloquea el sistema hasta que termina el proceso de copia?
Tienes alguna idea acerca de esto?
mira otra cosa yo antes la tenia en vb 2003 le hice un upgrade a 2005, y ahora pasa esto...
Bueno espero puedas responder, mientras tanto seguiré investigando.
mi correo es: la_yanete@hotmail.com
bueno, después de algunos dias de haber dejado por la paz la parte del sistema que me daba problemas, hoy nuevamente le dedique unos minutos y encontré la solución.
Iniciaba el segundo hilo donde queria generar la copia. Lo hacía asi:
Dim t As New Thread(AddressOf Lista.CopiarDatos)
t.Start()
Me daba este error:
"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it."
Me estaba faltando una linea:
Dim t As New Thread(AddressOf Lista.CopiarDatos)
t.TrySetApartmentState(Threading.ApartmentState.STA)
t.Start()
En vb.net 2003 funcionaba y en vb.net 2005 no. Me funcionó de esta manera.
La_yanete
Me da gusto que ya te funcionara.
Saludos
Hola!
Yo tengo un problema con un programa que compramos para monitoreo de alarmas se llama Winsamm versión 1.2, sucede que al abrir el wsreceiver aparece un mensaje que dice "Thread1 failed".
Nosotros lo usamos tal cual, sin meter codigo ni nada. El detalle es resolver ese problema.
Si alguien pudiera ayudarme se lo agradecería bastante.
para el problema del winsamm tengo una solucion definitiva, escribeme a everlastseguridad@programmer.net y t e lo cuento.
Un administrador del blog ha eliminado esta entrada.
I found this site using [url=http://google.com]google.com[/url] And i want to thank you for your work. You have done really very good site. Great work, great site! Thank you!
Sorry for offtopic
Thanks for your coment.
Publicar un comentario en la entrada
<< Home