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.
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
Seguimiento en mi blog sobre este tema:
http://help.superneurona.com/2006/09/problema-con-thread-en-vbnet-2005.html
Escucha mi podcast:
http://podcast.superneurona.com