Esperar a que los hilos acaben cuando termina un proceso

Una pregunta habitual relacionada con el desarrollo multihilo en plataforma .net es ¿Cómo espero a que los hilos que lanza mi aplicación acaben? El último que me la realizaba era uno de los alumnos del curso de Programación Multihilo que imparto en Campus MVP. No hay una respuesta única. La respuesta varia según se trate de un hilo que hemos creado explicitamente o un hilo que hayamos creado usando el pool de hilos de .Net.


El escenario que generalmente se plantea es que una aplicación lanza hilos, y queremos evitar que los hilos mueran sin concluir su trabajo cuando la aplicación termina.


Tenemos múltiples posibilidades:


Podemos antes de terminar el hilo principal de la aplicación, tener un tiempo durante el cual el hilo principal da tiempo a que el resto de hilos terminen. Para ello el hilo principal se duerme, y no crea más hilos. Para ello basta con poner una llamada a Sleep en las rutinas de finalización de nuestra aplicación.


//En aplicaciones Windows usamos el evento
//ThreadExit del objeto Application
static void Application_ThreadExit(object sender, EventArgs e)
{
  //Damos tiempo a que acaben los hilos ya lanzados…
  System.Threading.Thread.Sleep(10000);
}
 

//En servicios de Windows usamos la función OnStop
protected override void OnStop()
{
  //Damos tiempo a que acaben los hilos ya lanzados…
  System.Threading.Thread.Sleep(10000);
}
 

Pero esto puede no ser suficiente si necesitamos tener la certeza de que nuestros hilos acaben. Para ello podemos establecer IsBackground de los hilos que creamos a false.


Thread t = new Thread(new ThreadStart(ThreadMethod));
t.IsBackground = false;
t.Start();

De esta manera evitamos que el proceso muera mientras quedan hilos en ejecución. Eso si debemos tener en cuenta que esta aproximación puede interferir con el cierre de nuestras aplicaciones o incluso del sistema. Esto es especialmente molesto cuando los hilos los estamos creando en un servicio. Los servicios tienen un tiempo máximo para detenerse, trascurrido el cual el SCM lanza un error.


Cuando usamos el pool de hilos el proceso es un poco diferente, pues no tenemos acceso al hilo directamente. En cualquier caso desde la función de trabajo que pasamos a QueueUserWorkItem podemos obtener el hilo actual y establecer su propiedad IsBackground a false.


ThreadPool.QueueUserWorkItem(new WaitCallback(WorkMethod));

static void WorkMethod()
{
  //Antes de realizar ningún proceso establecemos la propiedad
  //IsBackgrount a true
  Thread.CurrentThread.IsBackground = false;
}

2 comentarios sobre “Esperar a que los hilos acaben cuando termina un proceso”

  1. hola Rodrigo,

    Ahora mismo no me acuerdo de memoria el código fuente en Java, pero tras pegarme con ¡hasta 8 hilos a la vez! y unos acababan antes que otros (imposible de depurar, pero lo conseguí), conseguí que no se quedasen abiertos. Después, realizas una join de ellos y después, les interrumpes(Interrupt). Por supuesto, esto debe ser controlado.

    Desconozco si tal funcionamiento es igual de bueno para .NET porque no me he pegado mucho con ellos en esta plataforma; pero ya sabes que te pegas con lo que la universidad exige.

    agur!

    PD: A punto de obtener el punto 3 del reto del «chico maravilla» ;). A ver si lo acabo antes de que déis la solución, pero como tengo que estudiar y hacer trabajos, no tengo demasiado tiempo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *