Cómo parar un thread

2072 vistas

Si una función de thread se ejecuta de forma contÃnua en un bucle, necesitaremos escribirlo de forma que con una condición pueda terminar dicho bucle. Esta condición tiene que poder ser modificada por otros threads. Retomemos el ejemplo del Form (ver FAQ [iurl=91&all=0&fs=464#467]Crear y lanzar un thread[/iurl]). Para señalar al thread que queremos que se detenga, vamos a usar un objeto de la clase System.Threading.AutoResetEvent. En el bucle de la función del thread hacemos esperar el thread durante un transcurso de tiempo. Si el objeto AutoResetEvent pasa al estado señalado, entonces salimos del thread.



vbnet
  1. Imports System.Threading
  2.  
  3. Public Class Threads
  4.     Inherits System.Windows.Forms.Form
  5.  
  6.     ' ........
  7.    
  8.     ' evento de señal de fin de thread private
  9.     Private _endThreadCalculsEvent As New AutoResetEvent(False)
  10.  
  11.     ' para parar un thread private
  12.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
  13.         ' el evento pasa al estado señalado
  14.         _endThreadCalculsEvent.Set()
  15.         ' esperamos el final del thread.
  16.         _threadCalculs1.Join()
  17.     End Sub
  18.  
  19.     ' función del thread private
  20.     Private Sub ThrFunc1()
  21.         Try
  22.             Calculs(1000)
  23.         Catch ex As Exception
  24.             Debug.WriteLine(ex.ToString())
  25.         End Try
  26.     End Sub
  27.  
  28.     Private Sub Calculs(ByVal tempo As Integer)
  29.     ' si el evento está en el estado señalado, WaitOne devuelve true y el bucle se termina.
  30.         While Not _endThreadCalculsEvent.WaitOne(tempo, False)
  31.             ' aquà será donde el thread hará su trabajo
  32.             ' .....
  33.         End While
  34.     End Sub
  35.  
  36. End Class



Existe una manera más radical de parar un thread; es la utilización de la función Thread.Abort. Cuando se realiza una llamada a Abort, el Runtime eleva una excepción ThreadAbortException que el thread puede interceptar. Es por esto que se desaconseja usar Abort, porque no podemos saber dónde se encuentra el thread en ese momento. Elevar una excepción puede provocar que el thread termine en una zona de trabajo que deba realizarse por completo antes de salir. No obstante hay situaciones en que podemos usarla sin peligro, como: la función del thread está bloqueada infinitamente en una llamada (una espera de conexión socket por ejemplo)



vbnet
  1. ' forzamos el fin del thread
  2.     Private Sub AbortThread()
  3.         ' pedimos al runtime que pare el Thread
  4.         _threadCalculs1.Abort()
  5.         ' esperamos el fin del thread
  6.         _threadCalculs1.Join()
  7.     End Sub



Un threads terminado no puede ser relanzado, tendremos que instanciar un nuevo objeto Thread.