您的位置:首页 > 编程语言

灵活使用多线程编程——EventWaitHandle类

2009-03-04 22:58 183 查看
EventWaitHandle类

表示一个线程同步事件。该类存在于mscorlib.DLL中。

EventWaitHandle类允许线程通过发信号的方式互相通信。 通常,一个或多个线程在EventWaitHandle上被阻止,直到一个未阻止的线程通过调用Set()方法,来释放一个或多个被阻止的线程。线程可以通过调用SignalAndWait()方法(该方法为静态函数)以原子操作的方式,向EventWaitHandle发出信号,然后在它上面阻止。

以终止的EventWaitHandle的行为取决于它的重置模式,在释放单个等待线程后,用EventResetMode.AutoReset标志创建的EventWaitHandle在终止时会自动地重置,用EventResetMode.ManualReset标志创建的EventWaitHandle一直保持终止状态,直到它的Reset函数被调用。

自动重置时间提供对资源的独占访问,如果没有线程等待时,自动重置事件处于终止状态。则该事件一直保持终止状态,直到某个线程尝试在该事件上等待,该事件释放线程,并立即重置,以阻止后面的线程。

手动重置事件类似于入口,当事件不处于终止状态时,在该事件上等待的线程则被阻止,当事件处于终止状态时,所有等待的线程均被释放,而事件一直保持终止状态(即后边的线程不阻止),直到它的Reset方法被调用,如果一个线程必须完成某项活动时,其他线程才能继续执行,则使用手动重置事件。

EventWaitHandle对象可以与其静态函数:WaitAll和WaitAny方法一起使用。

MSDN示例:

Code

1 using System;

2 using System.Threading;

3

4 public class Example

5 {

6 // The EventWaitHandle used to demonstrate the difference

7 // between AutoReset and ManualReset synchronization events.

8 //

9 private static EventWaitHandle ewh;

10

11 // A counter to make sure all threads are started and

12 // blocked before any are released. A Long is used to show

13 // the use of the 64-bit Interlocked methods.

14 //

15 private static long threadCount = 0;

16

17 // An AutoReset event that allows the main thread to block

18 // until an exiting thread has decremented the count.

19 //

20 private static EventWaitHandle clearCount =

21 new EventWaitHandle(false, EventResetMode.AutoReset);

22

23 [MTAThread]

24 public static void Main()

25 {

26 // Create an AutoReset EventWaitHandle.

27 //

28 ewh = new EventWaitHandle(false, EventResetMode.AutoReset);

29

30 // Create and start five numbered threads. Use the

31 // ParameterizedThreadStart delegate, so the thread

32 // number can be passed as an argument to the Start

33 // method.

34 for (int i = 0; i <= 4; i++)

35 {

36 Thread t = new Thread(

37 new ParameterizedThreadStart(ThreadProc)

38 );

39 t.Start(i);

40 }

41

42 // Wait until all the threads have started and blocked.

43 // When multiple threads use a 64-bit value on a 32-bit

44 // system, you must access the value through the

45 // Interlocked class to guarantee thread safety.

46 //

47 while (Interlocked.Read(ref threadCount) < 5)

48 {

49 Thread.Sleep(500);

50 }

51

52 // Release one thread each time the user presses ENTER,

53 // until all threads have been released.

54 //

55 while (Interlocked.Read(ref threadCount) > 0)

56 {

57 Console.WriteLine("Press ENTER to release a waiting thread.");

58 Console.ReadLine();

59

60 // SignalAndWait signals the EventWaitHandle, which

61 // releases exactly one thread before resetting,

62 // because it was created with AutoReset mode.

63 // SignalAndWait then blocks on clearCount, to

64 // allow the signaled thread to decrement the count

65 // before looping again.

66 //

67 WaitHandle.SignalAndWait(ewh, clearCount);

68 }

69 Console.WriteLine();

70

71 // Create a ManualReset EventWaitHandle.

72 //

73 ewh = new EventWaitHandle(false, EventResetMode.ManualReset);

74

75 // Create and start five more numbered threads.

76 //

77 for(int i=0; i<=4; i++)

78 {

79 Thread t = new Thread(

80 new ParameterizedThreadStart(ThreadProc)

81 );

82 t.Start(i);

83 }

84

85 // Wait until all the threads have started and blocked.

86 //

87 while (Interlocked.Read(ref threadCount) < 5)

88 {

89 Thread.Sleep(500);

90 }

91

92 // Because the EventWaitHandle was created with

93 // ManualReset mode, signaling it releases all the

94 // waiting threads.

95 //

96 Console.WriteLine("Press ENTER to release the waiting threads.");

97 Console.ReadLine();

98 ewh.Set();

99

100 }

101

102 public static void ThreadProc(object data)

103 {

104 int index = (int) data;

105

106 Console.WriteLine("Thread {0} blocks.", data);

107 // Increment the count of blocked threads.

108 Interlocked.Increment(ref threadCount);

109

110 // Wait on the EventWaitHandle.

111 ewh.WaitOne();

112

113 Console.WriteLine("Thread {0} exits.", data);

114 // Decrement the count of blocked threads.

115 Interlocked.Decrement(ref threadCount);

116

117 // After signaling ewh, the main thread blocks on

118 // clearCount until the signaled thread has

119 // decremented the count. Signal it now.

120 //

121 clearCount.Set();

122 }

123 }

124
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: