viernes, 10 de julio de 2015

Receta Multithreading en C# No. 2-6: Uso de la Clase CountdownEvent

Í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

Esta receta C# multithreading está orientada a estudiar la clase CountdownEvent, que como ya veremos es útil para controlar la finalización de tareas de un proceso a través del envío de una señal o mensaje, que indica el alcance de un determinado punto de ejecución.

1. Problema

Requerimos entender el proceso de envío de señales de punto de ejecución alcanzado en un proceso asociado a un thread. Además, se debe proveer el mecanismo de contador para controlar la completitud de un determinado número de threads.

2. Solución

La BCL de .NET Framework provee la clase CountdownEvent útil para este cometido.

3. Discusión de la Solución

La clase CountdownEvent [2] es considerada una primitiva de sincronización idónea para la gestión de conteo de número threads que han alcanzando el punto de registro de señal para indicar su finalización o alcance de un determinado punto de ejecución en un proceso.

Entre los miembros clave de esta clase tenemos:
  • Constructores:
    • CountDownEvent(int initialCount) [3]: este constructor crea una instancia de CountdownEvent con el número de señales esperadas a ser registradas por threads hasta que el contador llegue a cero (initialCount).
  • Métodos:
    • Signal [4]: Se registra una señal y decrementa el contador.
    • Wait [5]: Bloquea el thread actual hasta que el contador de registros (initialCount) de señales llegue a cero.
Por otro lado, podemos anotar además que:
"All public and protected members of CountdownEvent are thread-safe and may be used concurrently from multiple threads."
Como buena práctica al final del uso de una instancia de CountdownEvent, se recomiendo la invocación de Dispose [6] para la liberación de recursos usados en el control de conteo.


Y como sana sugerencia [1]:

"...there is a significant disadvantage; [...]Wait() will wait forever if we fail to call [...]Signal the required number of times. Please make sure that all your threads complete with the Signal method when using CountDownEvent."
Ahora, vayamos a la sección práctica.

4. Práctica: Código C#

Escribamos un ejemplo en C# para llevar un contador de los threads que han registrado una señal registro de finalización. Esto lo vamos a lograr haciendo uso de los artefactos de sincronización que provee la clase CountdownEvent:

En línea 13 instanciamos un objeto de CountdownEvent con un contador igual a 3.


Luego, en las líneas 23-25 creamos tres instancias de Thread y asociamos la expresión lambda para la ejecución del método EjecutarProceso. Inmediatamente después, líneas 28-30, iniciamos la ejecución de los threads con el método Start.


Dentro de EjecutarProceso (líneas 45-53) ocurren las siguientes operaciones:
  • Línea 48: Simulación de tarea larga con la invoación de Thread.Sleep(...).
  • Línea 49: Muestra mensaje en la salida estándar.
  • Línea 52: Registra señal de finalización con la invocación de Signal.
Mientras tanto en Main esperamos a que todos los tres (3) threads finalicen su ejecución con la invocación de Wait (línea 34). Cuando todos estos 3 threads hayan finalizado, mostramos el mensaje de satisfacción de la línea 36.

Finalmente, liberamos recursos explícitamente con la invocación de Dispose en la línea 40.

Compilación:

  1. csc /target:exe ConteoThreadsFinalizados.cs

Ejecución assembly:

  1. .\ConteoThreadsFinalizados.exe



> Prueba de ejecución (local):
Ejecución assembly ConteoThreadsFinalizados.exe
Animación 1. Ejecución assembly ConteoThreadsFinalizados.exe.

5. Conclusiones

Hemos elaborado un breve pero práctico estudio sobre la clase CountDownEvent. Esta clase es considerada una primitiva de sincronización destacable por permitir llevar la cuenta de threads finalizados a medida que estos emitan una señal de registro (Signal) y desde otro thread se controle su finalización satisfactoria.


La próxima receta C# multithreading estará centrada en el uso de la clase Barrier. Clase que es útil para la sincronización de threads que requiren ser organizados para el alcance de un punto de ejecución en concreto.

6. Glosario

  • .NET
  • BCL
  • Clase
  • Conteo
  • Evento
  • Registro
  • Sincronización
  • Señal

7. Literatura & Enlaces

[1]: Multithreading in C# 5.0 Cookbook by Eugene Agafonov. Copyright 2013 Eugene Agafonov, 978-1-84969-764-4.
[2]: CountdownEvent Class (System.Threading) - https://msdn.microsoft.com/en-us/library/system.threading.countdownevent(v=vs.110).aspx
[3]: CountdownEvent Constructor (System.Threading) - https://msdn.microsoft.com/en-us/library/system.threading.countdownevent.countdownevent(v=vs.110).aspx
[4]: CountdownEvent.Signal Method (System.Threading) - https://msdn.microsoft.com/en-us/library/dd321954(v=vs.110).aspx
[5]: CountdownEvent.Wait Method (System.Threading) - https://msdn.microsoft.com/en-us/library/dd270769(v=vs.110).aspx
[6]: CountdownEvent.Dispose Method (System.Threading) - https://msdn.microsoft.com/en-us/library/dd271048(v=vs.110).aspx


J

No hay comentarios:

Publicar un comentario

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