关于AutoResetEvent 和ManualResetEvent

在公司的代码里面看到这两个类的使用了,第一次去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 = 0,
        //
        // 摘要:
        //     当终止时,System.Threading.EventWaitHandle 释放所有等待的线程,并在手动重置前保持终止状态。
        ManualReset = 1,
    }

 

 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 = 0;

        /// <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 = 0; i <= 4; i++)
            {
                Thread t = new Thread(
                    new ParameterizedThreadStart(ThreadProc)
                );
                t.Start(i);
                Thread.Sleep(100);//确保线程是有先后顺序的  方便后面判断AutoReset是否随机释放单个线程
            }

            while (Interlocked.Read(ref threadCount) < 5)//等待所有的线程启动并阻塞
            {
                Thread.Sleep(500);
            }

            Console.WriteLine();

            while (Interlocked.Read(ref threadCount) > 0)//逐个释放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 = 0; i <= 4; i++)
            {
                Thread t = new Thread(
                    new ParameterizedThreadStart(ThreadProc)
                );
                t.Start(i);
            }

            
            while (Interlocked.Read(ref threadCount) < 5)//等待所有线程启动并阻塞
            {
                Thread.Sleep(500);
            }

            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不会阻塞,直接释放掉所有的线程。

 

posted @ 2014-11-10 18:50  ChuckLu  阅读(378)  评论(0编辑  收藏  举报