Hola, estoy desarrollando una aplicacion en vb 2005 y me ha surgido un problema. La aplicacion usa hilos y actualizcion de formularios desde los hilos. A continuación pogo parte del codigo (el codigo puede contener errores, porque lo he simplificado para que se entienda mejor):
Código:
1ª Version
Public Class Proceso
'La clase proceso es un formulario. Además dispone de una función (función
'proceso) que es ejecutada desde un hilo. Dentro del hilo se actualizan controles
'del formulario (para ello se recurre a metodos delegados y Invoke)
'Hilo principal en el que se ejecutara el proceso
Protected Hilo As Threading.Thread
Public Sub SetValue_Mensajes(ByVal hecho As String)
'Actualiza el campo de texto Mensajes. En el se muestran los mensajes
'sobre la evolución del proceso
'Se comprueba si el control ha sido llamado desde
'otro hilo
If (Mensajes.InvokeRequired) Then
'Acceso seguro a la propiedad value de Mensaje
'desde un Hilo
Dim delegado As SetValue_Mensajes_Delegado = New SetValue_Mensajes_Delegado(AddressOf SetValue_Mensajes)
'Me.Mensajes.Invoke(delegado, New Object() {hecho})
Else
'Sino quiere decir que se ha llamado desde el propio hilo
'asi que lo podemos modificar directamente
Me.Mensajes.Text = hecho
End If
End Sub
'Constructor
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
Dim delegadoPS As Threading.ThreadStart = New Threading.ThreadStart(AddressOf Me.FuncionProceso)
Hilo = New Threading.Thread(delegadoPS)
End Sub
'Funcion que se ejecuta desde el hilo
Public ub FuncionProceso()
....
'Calculos
....
'Actualizacion de control de formulario
Me.SetValue_Mensajes("Funciona")
...
End Sub
Public Function Ejecutar() As Integer
'Lanza el hilo para que ejecute la Funcion del Proceso.
Me.Hilo.Start()
End Sub
End Class
Public Class Main
Dim p As Proceso
Public Sub EjecutarMain()
p.Ejecutar()
End Sub
End Class
La version de Arriba funciona. El problema esta cuando complico un poco mas el asunto. Añado un hilo en la clase Main que es el que llama a la funcion ejecutar de Proceso, es decir, tendria hilos anidados. El codigo de la clase Main queda de la siguiente manera:
Código:
2ª Version
Public Class Main
Private HiloMain As Threading.Thread
Dim p As Proceso
Public Sub New()
Dim delegadoPS As Threading.ThreadStart = New Threading.ThreadStart(AddressOf Me.FuncionMain)
HiloMain = New Threading.Thread(delegadoPS)
End Sub
'Funcion que se ejecuta desde el hilo
Public ub FuncionMain()
p = New Proceso()
Dim EventosEspera As Threading.AutoResetEvent()
ReDim EventosEspera(0)
EventosEspera(0)=p.EventoEspera
p.Ejecutar()
'Esperar a que termine de ejecutarse el hilo del proceso
System.Threading.WaitHandle.WaitAll(EventosEspera)
End Sub
Public Sub EjecutarMain()
Me.HiloMain.Start()
End Sub
End Class
'Además tambien se a cambiado un poco el codigo de la clase proceso, añadiendo
'una propiedad llamada EventoEspera que es de tipo AutoResetEvent. Esta
'propiedad se inicializa en el constructor de new (se pone como no señalizado)
'y pasa a señalizado al final de FuncionProceso.
'Funcion que se ejecuta desde el hilo
Public ub FuncionProceso()
....
'Calculos
....
'Actualizacion de control de formulario
Me.SetValue_Mensajes("Funciona")
...
Me.EventoEspera.Set()
End Sub
En esta segunda versión la aplicacion se queda colgada. La aplicación se cuelga en el momento de llamar a Invoke, no muestra ningun mensaje de error simplemente se queda colgada. Yo creo que se debe a que existan hilos anidados, pero no se como solucionarlo. Si comento la linea de Invoke todo funciona bien, bueno aunque el formulario no se refresca (aparece en blanco), pero el codigo en sí se ejecuta bien.
Si alguien sabe porque se cuelga al llamar al metodo Invoke y como podría solucionarlo le estaria muy agradecido. Un saludo a todos y muchas gracías.