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 (); } } }