先看一段代码:
public
class WaitHandlerExample {
public
static AutoResetEvent waitHandler;
public
static ManualResetEvent manualWaitHandler;
public
static
void ThreadPoolMain() {
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
waitHandler =
new AutoResetEvent(
false);
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
manualWaitHandler =
new ManualResetEvent(
false);
// Queue the task.
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc));
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
ThreadPool.QueueUserWorkItem(
new WaitCallback(ThreadProc2));
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
Console.WriteLine(
"Main thread does some work, then waiting....");
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
manualWaitHandler.WaitOne();
//waitHandler.Reset();
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
manualWaitHandler.WaitOne();
//waitHandler.Reset();
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
Console.WriteLine(
"Main thread exits.");
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
}
// This thread procedure performs the task.
public
static
void ThreadProc(Object stateInfo) {
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
Thread.Sleep(1000);
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
Console.WriteLine(
"Hello from the thread pool.");
//waitHandler.Set(); //
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
manualWaitHandler.Set();
//过去了,但是没关,也就是说 信号还是开着的。
//manualWaitHandler.Reset();
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
}
public
static
void ThreadProc2(
object stateInfo) {
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
Thread.Sleep(100);
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
Console.WriteLine(
"Hello from the thread Pool2");
//waitHandler.Set();
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
manualWaitHandler.Set();
//过去了,但是没有关
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
}
![](https://i-blog.csdnimg.cn/blog_migrate/2e2afaebf8dcf88b85312bc4cc791bb4.png)
}
如果把 AutoResetEvent 比作 北京地铁的门闸,那么
AutoResetEvent waitHandler=new AutoResetEvent(false);
可以看作,初始化闸机口为关闭状态,
waitHandler.WaitOne();
可以看作刷卡
waitHandler.Set()
表示通过,并且闸机自动关闭(AutoReset)为下次通过做准备。他的一个重大的好处,就是线程只能一个一个通过,保持了顺序又避免了死锁。
如果使用manualResetEvent 呢,那么在waitHandler.Set 之后,必须调用Reset()方法,为下面一位进去做好准备, 否则,就相当于无法再次刷卡。
体现在程序中就是,AutoResetEvent 可以WaitOne 很多次,可是ManualResetEvent 如果不Reset 下次就不能使用. 这就是他们的区别。