代码改变世界

转:一个实例明白AutoResetEvent和 ManulResetEvent的用法

2012-11-16 20:27  starlet  阅读(269)  评论(0编辑  收藏  举报

先看一段代码:

        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 下次就不能使用. 这就是他们的区别。

本文出自 “Xhinker” 博客,转载请与作者联系!