miércoles, 3 de septiembre de 2014

Receta C# No. 4-13: Finalizar la Ejecución de un Thread

Índice

0. Introducción
1. Problema
2. Solución
3. Discusión de la Solución
4. Práctica: Código C#
5. Conclusiones
6. Glosario
7. Literatura & Enlaces

0. Introducción

Empezamos ahora con la preparación de una receta en C# donde conoceremos acerca del proceso de terminación o finalización de un thread en ejecución. Existirá o surgirá una o varias situaciones en la que sea necesario ejecutar esta operación sobre un thread: terminación de un proceso relacionado con el thread, ciclo de ejecución de un programa que ha terminado abruptamente, un sistema de monitorización de recursos detecta baja disponibilidad de estos y procede a su liberación, entre otras situaciones. Esto lo llevaremos a cabo con el uso de uno de los miembros de la clase System.Threading.Thread: Abort.

1. Problema

Encontrar un elemento de programa de la biblioteca base de clases de .NET Framework para finalizar arbitrariamente la ejecución de un thread.

2. Solución

Encontramos que la clase Thread (System.Threading) cuenta con el miembro, método en particular, Abort para terminar la ejecución de un thread.

3. Discusión de la Solución

Desde código cliente podemos invocar el método Abort [6] para terminar la ejecución de un thread. Este método cuenta con dos versiones sobrecargadas:
Versiones sobrecargadas de Abort
Figura 1. Versiones sobrecargadas de Abort [6].
Con este método, de forma implícita, la CLR genera genera una excepción ThreadAbortException [7] en el cuerpo de implementación del método adyacente. Sin embargo, hay que tener en mente que no podemos asumir que el thread haya terminado ipso facto; para garantizarlo existen alternativas programáticas más elegantes y sofisticadas que ya hemos discutidos en recetas C# anteriores:
Por otro lado, también hay que considerar la generación de la excepción ThreadAbortException y la posibilidad de reanudar la ejecución del thread (desde luego, siempre que sea necesario) dentro del bloque catch que parte del código de implementación del método en donde se genera la excepción en cuestión. Esto lo logramos con la invocación del método static Thread.ResetAbort [8].

[Nota: La receta especializada en temas de multithreading Abortar un en Ejecución hace un cubrimiento más riguroso a nivel teórico y práctico del método Abort; así que sugiero su lectura para saber más sobre este proceso de terminación de la ejecución de un thread.]

4. Práctica: Código C#

Ahora realizaremos una adaptación del ejemplo hallado en [1] para demostrar cómo terminar un thread en ejecución. El ejemplo consiste en mostrar repetidamente mensajes en la salida estándar hasta que el usuario de la aplicación decida presionar la tecla Enter.

En las líneas 46-76 declaramos el método MostrarMensaje; este método se ejecuta en un thread distinto a Main. En la línea 54 mostramos un mensaje de estado de la ejecución del thread: hora exacta. Por cada iteración del ciclo while (líneas 50-60) se realiza una pausa/espera de un (1) segundo. Ahora, en el método Main (líneas 9-42) creamos un objeto Thread al que asociamos el método MostrarMensaje (línea 15). Sobre la línea 24 invocamos al método Start para iniciar la ejecución del thread; la ejecución de este thread no va a terminar sino hasta que el usuario presione la tecla `Enter`. Cuando lleva a cabo la tarea sugerida para la terminación de la ejecución del thread, se invoca el método Abort para enviar la señal de finalización. Enseguida, invocamos al método Join para dejar que el thread finalice con las tareas del bloque catch (líneas 62-75) declarado en el método MostrarMensaje.

Compilación:


  1. csc /target:exe FinalizarEjecucionThread.cs

Ejecución assembly:


  1. .\FinalizarEjecucionThread.exe

> Prueba de ejecución (ideone.com).

> Prueba de ejecución (local):
Ejecución assembly FinalizarEjecucionThread.exe
Figura 2. Ejecución assembly FinalizarEjecucionThread.exe.

5. Conclusiones

La terminación de la ejecución thread y en consecuencia de su proceso adyacente se realiza a través de la invocación del método de instancia Abort de la clase Thread. El uso de este método debe ser cuidadoso debido a que su finalización comprende el lanzamiento de la excepción ThreadAbortException por parte de la CLR. Sin embargo, C# ofrece otras alternativas más amigables y sofisticadas: las técnicas de sincronización de threads Monitor, Evento, y Exclusión Mutua (Mutex). En la próxima receta abordaremos la creación de una colección de threads.

6. Glosario

  • CLR
  • Evento
  • Excepción
  • Monitor
  • Multithreading
  • Mutex
  • Thread

7. Literatura & Enlaces

[1]: Visual C# 2010 Recipes by Allen Jones and Adam Freeman. Copyright 2010 Allen Jones and Adam Freeman, 978-1-4302-2525-6.
[2]: Receta Multithreading en C# No. 1-4: Abortar un Thread en Ejecución | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/06/receta-multithreading-en-csharp-no-1-4-abortar-un-thread-en-ejecucion.html
[3]: Receta C# No. 4-7: Sincronizar la Ejecución de Múltiples Threads usando un Monitor | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/receta-csharp-no-4-7-sincronizar-la-ejecucion-de-multiples-threads-usando-un-monitor.html
[4]: Receta C# No. 4-8: Sincronizar la Ejecución de Múltiples Threads usando un Evento | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/receta-c-no-4-8-sincronizar-la-ejecucion-de-multiples-threads-usando-un-evento.html
[5]: Receta C# No. 4-9: Sincronización de Múltiples Threads usando Mutex | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/07/receta-csharp-no-4-9-sincronizacion-de-multiples-threads-usando-mutex.html
[6]: Thread.Abort Method (System.Threading) - http://msdn.microsoft.com/en-us/library/system.threading.thread.abort(v=vs.110).aspx
[7]: ThreadAbortException Class (System.Threading) - http://msdn.microsoft.com/en-us/library/system.threading.threadabortexception(v=vs.110).aspx
[8]: Thread.ResetAbort Method (System.Threading) - http://msdn.microsoft.com/en-us/library/system.threading.thread.resetabort(v=vs.110).aspx


M

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.