fork download
  1. using System;
  2. using System.Threading;
  3.  
  4. namespace Recetas.CSharp.Cap04.R0408
  5. {
  6. public sealed class RecetaEventWaitHandle
  7. {
  8. // Valor centinela para notificar cuando el
  9. // segundo thread debe terminar:
  10. private static bool terminar = false;
  11.  
  12. // Método utilitario para la presentación de información
  13. // del estado de ejecución:
  14. private static void Rastreo(string mensaje)
  15. {
  16. Console.WriteLine ("[{0,3}] - {1} : {2}",
  17. Thread.CurrentThread.ManagedThreadId,
  18. DateTime.Now.ToString("HH:mm:ss.ffff"),
  19. mensaje
  20. );
  21. }
  22.  
  23. // Método que se ejecutará en un thread nuevo. Este método
  24. // espera a que un objeto EventWaitHandle genera una señal antes
  25. // de mostrar un mensaje en la salida estándar:
  26. private static void MostrarMensaje ()
  27. {
  28. // Captura un objeto EventWaitHandle con la invocación
  29. // del método OpenExisting:
  30. EventWaitHandle evento = EventWaitHandle.OpenExisting ("EventoEjemplo");
  31.  
  32. Rastreo ("El método `MostrarMensaje` se ha iniciado.");
  33.  
  34. while (!terminar)
  35. {
  36. // Sobre el objeto EventWaitHandle se hace una espera de 2 segundos
  37. // y mientras que no se notifique al objeto EventWaitHandle
  38. // el valor de retorno de WaitOne será false:
  39. if (evento.WaitOne (2000, true))
  40. {
  41. Rastreo ("EventWaitHandle en estado notificado.");
  42. }
  43. else
  44. {
  45. Rastreo ("EventWaitHandle en estado no-notificado.");
  46. }
  47.  
  48. // Espera de dos segundos:
  49. Thread.Sleep (2000);
  50. }
  51. Rastreo ("El thread está a punto de terminar.");
  52. }
  53.  
  54. public static void Main()
  55. {
  56. // Creación de instancia de EventWaitHandle:
  57. using (EventWaitHandle evento =
  58. new EventWaitHandle (true, EventResetMode.ManualReset, "EventoEjemplo"))
  59. {
  60. // Creación de un thread:
  61. Rastreo ("Iniciando un nuevo thread.");
  62. Thread t = new Thread (MostrarMensaje);
  63. t.Start ();
  64.  
  65. // Facilita alternar entre los estados signaled y unsignaled
  66. // a la instancia EventWaitHandle:
  67. for (int i = 0; i < 3; ++i)
  68. {
  69. Console.WriteLine ("\nPresione la tecla Enter...");
  70. Console.ReadLine ();
  71.  
  72. // Para conocer el estado del objeto EventWaitHandle, es
  73. // necesario invocar al método WaitOne con 0 segundos
  74. // de retraso:
  75. if (evento.WaitOne (0, true))
  76. {
  77. Rastreo ("Pasando el evento a estado no-señalado (unsignaled).");
  78.  
  79. // El evento (EventWaitHandle) es notificado:
  80. evento.Reset();
  81. }
  82. else
  83. {
  84. Rastreo ("Pasando el evento a estado señalado (signaled).");
  85.  
  86. evento.Set();
  87. }
  88. }
  89.  
  90. // Finalizamos la ejecución del método MostrarMensaje:
  91. terminar = true;
  92. // Permitimos su ejecución:
  93. evento.Set();
  94. // Esperamos a que terminen todos los threads:
  95. t.Join (5000);
  96. }
  97.  
  98. Console.WriteLine ("\nEl thread Main ha terminado. Presione Enter");
  99. Console.ReadLine ();
  100.  
  101.  
  102. }
  103. }
  104. }
Success #stdin #stdout 0.05s 34928KB
stdin
Standard input is empty
stdout
[  1] - 18:12:43.8010 : Iniciando un nuevo thread.

Presione la tecla Enter...
[  3] - 18:12:43.8517 : El método `MostrarMensaje` se ha iniciado.
[  3] - 18:12:43.8529 : EventWaitHandle en estado notificado.
[  1] - 18:12:43.8531 : Pasando el evento a estado no-señalado (unsignaled).

Presione la tecla Enter...
[  1] - 18:12:43.8536 : Pasando el evento a estado señalado (signaled).

Presione la tecla Enter...
[  1] - 18:12:43.8538 : Pasando el evento a estado no-señalado (unsignaled).
[  3] - 18:12:45.8542 : El thread está a punto de terminar.

El thread Main ha terminado. Presione Enter