关于AutoResetEvent 和ManualResetEvent

时间:2022-08-29 07:04:32

在公司的代码里面看到这两个类的使用了,第一次去msdn上的时候,看的一头雾水(关键是没有找对方法)

http://www.cnblogs.com/qingyun163/archive/2013/01/05/2846633.html      这篇博客应该会有些帮助的

这次看的比较仔细,懂得看一个类的时候,可以去找它的父类。

发现AutoResetEvent 和ManualResetEvent 全部都继承自EventWaitHandle类

EventWaitHandle中有介绍EventResetMode 这个枚举类型  

    // 摘要:
// 指示在接收信号后是自动重置 System.Threading.EventWaitHandle 还是手动重置。
[ComVisible(false)]
public enum EventResetMode
{
// 摘要:
// 当终止时,System.Threading.EventWaitHandle 在释放一个线程后自动重置。如果没有等待的线程,System.Threading.EventWaitHandle
// 将保持终止状态直到一个线程阻止,并在释放此线程后重置。
AutoReset = ,
//
// 摘要:
// 当终止时,System.Threading.EventWaitHandle 释放所有等待的线程,并在手动重置前保持终止状态。
ManualReset = ,
}
 EventResetMode 枚举的代码示例
using System;
using System.Threading; namespace MyEventResetMode
{
class Program
{
/// <summary>
/// EventWaitHandle变量 可以赋值AutoReset和ManualReset
/// </summary>
private static EventWaitHandle ewh; /// <summary>
/// 线程的计数器 在进入线程后加1 释放线程后减1
/// </summary>
private static long threadCount = ; /// <summary>
/// 让主线程阻塞的 EventWaitHandle 到所有开辟出来的线程全部被释放
/// </summary>
private static EventWaitHandle clearCount = new EventWaitHandle(false, EventResetMode.AutoReset); static void Main(string[] args)
{
//创建一个AutoReset类型的EventWaitHandle
ewh = new EventWaitHandle(false, EventResetMode.AutoReset); //创建5个线程,将i作为参数传递,以识别不同的线程
for (int i = ; i <= ; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
Thread.Sleep();//确保线程是有先后顺序的 方便后面判断AutoReset是否随机释放单个线程
} while (Interlocked.Read(ref threadCount) < )//等待所有的线程启动并阻塞
{
Thread.Sleep();
} Console.WriteLine(); while (Interlocked.Read(ref threadCount) > )//逐个释放ewh阻塞的线程
{
Console.WriteLine("Press ENTER to release a waiting thread.");
Console.ReadLine(); WaitHandle.SignalAndWait(ewh, clearCount);//向一个 WaitHandle 发出信号并等待另一个。 相当于下面两个语句
/*
ewh.Set();//收到信号之后,随机释放一个被它阻塞的线程,其它的保持阻塞
clearCount.WaitOne();//阻塞
*/
//ewh是要发出信号的WaitHandle, ewh收到信号之后,释放单个线程,然后再自动阻塞
//clearCount是要等待的WaitHandle clearCount在此等待 相当于调用了clearCount.WaitOne(); }
Console.WriteLine(); //创建一个ManualReset类型的EventWaitHandle
ewh = new EventWaitHandle(false, EventResetMode.ManualReset); //创建5个线程,将i作为参数传递,以识别不同的线程
for (int i = ; i <= ; i++)
{
Thread t = new Thread(
new ParameterizedThreadStart(ThreadProc)
);
t.Start(i);
} while (Interlocked.Read(ref threadCount) < )//等待所有线程启动并阻塞
{
Thread.Sleep();
} Console.WriteLine("Press ENTER to release the waiting threads.");
Console.ReadLine();
ewh.Set(); //一次释放所有被它阻塞的线程 Console.Read();
} public static void ThreadProc(object data)
{
int index = (int)data; Interlocked.Increment(ref threadCount);//计数增加
Console.WriteLine("Thread {0} blocks.", data);
ewh.WaitOne();//等待ewh发出信号 Console.WriteLine("Thread {0} exits.", data);
Interlocked.Decrement(ref threadCount);//计数减少 clearCount.Set();//释放主线程一次
}
}
}

EventWaitHandle需要注意的是,如果初始设置为false,那么就会阻塞线程。

如果初始为true,AutoReset会先释放掉等待线程中的任意一个,其他的线程仍保持阻塞。如果初始为true,ManualReset不会阻塞,直接释放掉所有的线程。