Ver Mensaje Individual
  #1 (permalink)  
Antiguo 16/10/2008, 10:17
Licantropo28
 
Fecha de Ingreso: octubre-2008
Mensajes: 12
Antigüedad: 16 años, 4 meses
Puntos: 0
Threads y actualizacion de controles creados fuera del Hilo.

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.