A cuerda de una pregunta en el foro (para principiantes), donde se cuestiona porque el ‘timer’ deja de funcionar y no refresca el paso de los segundos cuando efectuamos una llamada a un procedimiento… vamos a exponer el siguiente argumento para intentar esclarecerlo.
Nuestro ‘Form’ se está rondando en su hilo de ejecución… por lo que cuando efectúas la llamada para «procesar la rutina», el ‘timer’ deja de refrescarse por falta de turno de ejecución al estar (nuestro hilo) ocupado en espera de recibir el retorno de la llamada a tal procedimiento.
Para no bloquear nuestro hilo de ejecución y poder continuar con otras tareas, deberemos llamar a ese proceso creando un nuevo hilo de ejecución, utilizando ‘Threading.Thread’ … aquí dejo un ejemplo donde muestra las dos situaciones de una forma muy básica.
En situación de ejecución, nuestro ‘form’ visualiza la fecha y hora actual en la barra de titulo. Al pulsar sobre el botón 1 se lanza la llamada al procedimiento ‘readline’ en espera de leer una línea recibida por el puerto serie, todo el ‘form’ quedara congelado hasta recibir esa línea, que de buena tinta sabemos que nunca llegara J por lo tanto la barra de titulo quedara inanimada, pues el hilo está ocupado y el ‘timer1’ no dispone de turno de ejecución para dispar los eventos ‘tick’.
Sin embargo al hacer clic sobre el segundo botón, este crea un nuevo hilo de ejecución que apunta al mismo procedimiento pero con una nueva asignacion de ejecucion, haciendo autónomo su proceso en la llamada al procedimiento, así pues en este caso la barra de titulo reflejara en todo momento la fecha y hora, con independencia de si el procedimiento a finalizado o no, pues el hilo principal del ‘form’ continuara atendiendo y repartiendo la ejecución entre todos los objetos que tiene a su cargo… inclusive el nuevo hilo.
Para rodar este ejemplo, solo tienes que crear un nuevo proyecto ‘winform’ añadir un ‘timer’ y dos ‘Button’.
Espero que os sea útil y pido ‘sorrys’ por el rollo!
Pep Lluis,
Public Class Form1
Private Puerto As New System.IO.Ports.SerialPort
Private Sub Form1_Load(…..) Handles MyBase.Load
Me.Timer1.Interval = 1000
Me.Timer1.Enabled = True
Me.Button1.Text = «Llamar Procedimiento»
Me.Button2.Text = «Ejecutar nuevo Hilo»
Puerto = My.Computer.Ports.OpenSerialPort(«COM1»)
End Sub
Private Sub Timer1_Tick(…..) Handles Timer1.Tick
Me.Text = Date.Now
End Sub
Private Sub Button1_Click(…..) Handles Button1.Click
Me.Button1.Enabled = False
Me.Text = «*Ejecucion sin crear Hilo «
Procedimiento()
Me.Button1.Enabled = True
End Sub
Private Sub Button2_Click(…..) Handles Button2.Click
Me.Button2.Enabled = False
Me.Text = «*Ejecutar creando un nuevo Hilo»
Dim MiHilo As New Threading.Thread(AddressOf Procedimiento)
MiHilo.Start()
‘el timer continua con su ejecucion…
‘Antes de lanzar una nueva llamada
‘deberiamos cancelar el hilo en espera
‘ejecutando : MiHilo.Abort() o controlando
‘su estado o control por ejemplo con :
‘MiHilo.IsAlive
‘MiHilo.Suspend()
‘MiHilo.Sleep()
End Sub
Private Sub Procedimiento()
‘
‘Esta funcion esta efectuando una llamada
‘a un procedimento que no finalizara hasta
‘completarse o exceder su tiempo de espera.
Dim datos = Puerto.ReadLine
End Sub
End Class