using System;
using System.Threading;
namespace Recetas.CSharp.Cap04.R0410
{
public sealed class SincronizacionConsola
{
// Determina el estado de ejecución de un thread:
private static bool terminarThread = false;
// Muestra mensajes de información acerca del estado
// de ejecución de un thread:
private static void Rastrear(string mensaje)
{
Console.WriteLine ("[{0,3}] - {1} : {2}",
Thread.CurrentThread.ManagedThreadId,
DateTime.Now.ToString("HH:mm:ss.ffff"),
mensaje
);
}
// Método a encapsular por diferentes threads y que
// contiene una región crítica protegida por un
// objeto Semaphore:
private static void MostrarMensajeEnConsola()
{
// Se apropia de un instancia Semaphore con nombre
// 'EjemploSemaphore':
using (Semaphore semaforo = Semaphore.OpenExisting ("EjemploSemaphore"))
{
Rastrear("Inicio ejecución de thread.");
while (!terminarThread)
{
// Apoderamiento del semaforo:
semaforo.WaitOne();
Rastrear("Apoderamiento del Semaphore.");
Thread.Sleep(1000);
Rastrear ("Liberación del Semaphore.");
semaforo.Release();
// Pausa para dar la oportunidad de que otro
// thread se apodere del semaforo:
Thread.Sleep (100);
}
Rastrear ("A punto de finalizar un thread.");
}
}
public static void Main()
{
Console.Title = "Demostración uso de Sincronización con Semaphore";
Console.WriteLine ();
// Creación de una instancia de Semaphore llamada `EjemploSemaphore`:
using (Semaphore semaforo = new Semaphore (2, 2, "EjemploSemaphore"))
{
Rastrear ("Inicio de ejecución de threads. Presione Enter para finalizar.");
// Creación de 3 threads:
Thread t1 = new Thread (MostrarMensajeEnConsola);
Thread t2 = new Thread (MostrarMensajeEnConsola);
Thread t3 = new Thread (MostrarMensajeEnConsola);
t1.Start();
t2.Start();
t3.Start();
// Para finalizar se debe presionar Enter:
Console.ReadLine ();
// Finaliza los threads asociados con el método `MostrarMensajeEnConsola`,
// y espera a que se completan antes de deshechar la instancia Semaphore:
terminarThread = true;
t1.Join(5000);
t2.Join(5000);
t3.Join(5000);
}
}
}
}