先看一段代碼:
public class WaitHandlerExample {
public static AutoResetEvent waitHandler;
public static ManualResetEvent manualWaitHandler;
public static void ThreadPoolMain() {
waitHandler = new AutoResetEvent(false);
manualWaitHandler = new ManualResetEvent(false);
// Queue the task.
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc));
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc2));
Console.WriteLine("Main thread does some work, then waiting....");
manualWaitHandler.WaitOne();
//waitHandler.Reset();
manualWaitHandler.WaitOne();
//waitHandler.Reset();
Console.WriteLine("Main thread exits.");
}
// This thread procedure performs the task.
public static void ThreadProc(Object stateInfo) {
Thread.Sleep(1000);
Console.WriteLine("Hello from the thread pool.");
//waitHandler.Set(); //
manualWaitHandler.Set();//過去了,但是沒關,也就是說 信號還是開着的。
//manualWaitHandler.Reset();
}
public static void ThreadProc2(object stateInfo) {
Thread.Sleep(100);
Console.WriteLine("Hello from the thread Pool2");
//waitHandler.Set();
manualWaitHandler.Set();//過去了,但是沒有關
}
}
如果把 AutoResetEvent 比作 北京地鐵的門閘,那麼
AutoResetEvent waitHandler=new AutoResetEvent(false);
可以看作,初始化閘機口爲關閉狀態,
waitHandler.WaitOne();
可以看作刷卡
waitHandler.Set()
表示通過,並且閘機自動關閉(AutoReset)爲下次通過做準備。他的一個重大的好處,就是線程只能一個一個通過,保持了順序又避免了死鎖。
如果使用manualResetEvent 呢,那麼在waitHandler.Set 之後,必須調用Reset()方法,爲下面一位進去做好準備, 否則,就相當於無法再次刷卡。
體現在程序中就是,AutoResetEvent 可以WaitOne 很多次,可是ManualResetEvent 如果不Reset
下次就不能使用. 這就是他們的區別。