using System;
using System.Threading;
namespace Recetas.CSharp.Cap04.R0408
{
public sealed class RecetaEventWaitHandle
{
// Valor centinela para notificar cuando el
// segundo thread debe terminar:
private static bool terminar = false;
// Método utilitario para la presentación de información
// del estado de ejecución:
private static void Rastreo(string mensaje)
{
Console.WriteLine ("[{0,3}] - {1} : {2}",
Thread.CurrentThread.ManagedThreadId,
DateTime.Now.ToString("HH:mm:ss.ffff"),
mensaje
);
}
// Método que se ejecutará en un thread nuevo. Este método
// espera a que un objeto EventWaitHandle genera una señal antes
// de mostrar un mensaje en la salida estándar:
private static void MostrarMensaje ()
{
// Captura un objeto EventWaitHandle con la invocación
// del método OpenExisting:
EventWaitHandle evento = EventWaitHandle.OpenExisting ("EventoEjemplo");
Rastreo ("El método `MostrarMensaje` se ha iniciado.");
while (!terminar)
{
// Sobre el objeto EventWaitHandle se hace una espera de 2 segundos
// y mientras que no se notifique al objeto EventWaitHandle
// el valor de retorno de WaitOne será false:
if (evento.WaitOne (2000, true))
{
Rastreo ("EventWaitHandle en estado notificado.");
}
else
{
Rastreo ("EventWaitHandle en estado no-notificado.");
}
// Espera de dos segundos:
Thread.Sleep (2000);
}
Rastreo ("El thread está a punto de terminar.");
}
public static void Main()
{
// Creación de instancia de EventWaitHandle:
using (EventWaitHandle evento =
new EventWaitHandle (true, EventResetMode.ManualReset, "EventoEjemplo"))
{
// Creación de un thread:
Rastreo ("Iniciando un nuevo thread.");
Thread t = new Thread (MostrarMensaje);
t.Start ();
// Facilita alternar entre los estados signaled y unsignaled
// a la instancia EventWaitHandle:
for (int i = 0; i < 3; ++i)
{
Console.WriteLine ("\nPresione la tecla Enter...");
Console.ReadLine ();
// Para conocer el estado del objeto EventWaitHandle, es
// necesario invocar al método WaitOne con 0 segundos
// de retraso:
if (evento.WaitOne (0, true))
{
Rastreo ("Pasando el evento a estado no-señalado (unsignaled).");
// El evento (EventWaitHandle) es notificado:
evento.Reset();
}
else
{
Rastreo ("Pasando el evento a estado señalado (signaled).");
evento.Set();
}
}
// Finalizamos la ejecución del método MostrarMensaje:
terminar = true;
// Permitimos su ejecución:
evento.Set();
// Esperamos a que terminen todos los threads:
t.Join (5000);
}
Console.WriteLine ("\nEl thread Main ha terminado. Presione Enter");
Console.ReadLine ();
}
}
}