Cómo parar un thread

2532 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.



csharp
  1. using System.Threading;
  2. public class Thread : System.Windows.Forms.Form
  3. {
  4.   // ........
  5.   // evento de señal de fin de thread private
  6.   AutoResetEvnet _endThreadCalculsEvent = new AutoResetEvent(false);
  7.  
  8.   // para parar un thread private
  9.   void Button2_Click(Object sender, System.EventArgs e)
  10.   {
  11.     // el evento pasa al estado señalado
  12.     _endThreadCalculsEvent.Set();
  13.  
  14.     // esperamos el final del thread.
  15.     _threadCalculs1.Join();
  16.   }
  17.  
  18.   // función del thread private
  19.   void ThrFunc1()
  20.   {
  21.     try
  22.     {
  23.       Calculs(1000);
  24.     }
  25.     catch (Exception ex)
  26.     {
  27.       Debug.WriteLine(ex.ToString());
  28.     }
  29.   }
  30.  
  31.   private void Calculs(int tempor)
  32.   {
  33.     // si el evento está en el estado señalado, WaitOne devuelve true y el bucle se termina.
  34.     while (! _endThreadCalculsEvent.WaitOne(tempo, false) )
  35.     {
  36.       // aquà será donde el thread hará su trabajo
  37.       // .....
  38.     }
  39.   }
  40. }



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)



csharp
  1. // forzamos el fin del thread
  2. private void AbortThread()
  3. {
  4.   _threadCalculs1.Abort();
  5.   // pedimos al runtime que pare el Thread
  6.  
  7.   _threadCalculs1.Join();
  8.   // esperamos el fin del thread
  9. }



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