陕西队西北狼

AutoResetEvent详解

在MSDN中,它的解释为:通知正在等待的线程已发生事件。无法继承此类(密封类)。

AutoResetEvent 允许线程通过发信号进行相互通信,例如发Set信号,让正在WaitOne等待信号着的线程开启继续执行。通常,此通信涉及线程需要独立访问的资源。

线程通过调用 AutoResetEvent 上的WaitOne来等待信号。如果 AutoResetEvent 处于非终止状态,则该线程阻塞,并等待当前控制资源的线程通过调用 Set发出资源可用的信号。

调用 Set 向 AutoResetEvent 发信号以释放等待线程,这里释放的是有WaitOne等待着的随机的某一个线程 ,而不是所有有WaitOne等待信号的线程,此时AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。如果没有任何线程在等待(没有一个线程有WaitOne等待信号),则状态将无限期地保持为终止状态。

 

它可以通过将一个布尔值传递给构造函数来控制 AutoResetEvent 的初始状态,如果初始状态为终止状态,则为 true;否则为 false

 

示例代码:

实现类源码:

class AutoResetEventTest
    {
        private AutoResetEvent are;

        public AutoResetEventTest()
        {
            this.are = new AutoResetEvent(false);
        }

        /// <summary>
        /// 放行等待的线程
        /// </summary>
        public void Set()
        {
            this.are.Set();
        }

        /// <summary>
        /// 暂停正在等待的线程
        /// </summary>
        public void Reset()
        {
            this.are.Reset();
        }

        /// <summary>
        /// 启动N个线程,可以手动传入参数指定启动几个线程
        /// </summary>
        /// <param name="threadNumber"></param>
        public void CreateThreads(int threadNumber)
        {
            Thread[] threads = new Thread[threadNumber];

            for (int i = 0; i < threadNumber; i++)
            {
                threads[i] = new Thread(new ThreadStart(Run));
                threads[i].Start();
            }
        }

        /// <summary>
        /// 正在等待着的线程,该线程打印出线程ID
        /// </summary>
        private void Run()
        {
            string threadId = string.Empty;
            try
            {
                while (true)
                {
                    // 阻塞当前线程
                    this.are.WaitOne();

                    threadId = Thread.CurrentThread.ManagedThreadId.ToString();
                    Console.WriteLine("Run---Thread(" + threadId + ") is running...");

                    Thread.Sleep(3000);
                }
            }
            catch (Exception ex)//异常处理
            {
                Console.WriteLine("Run---Thread(" + threadId + ") Error happend!:" + ex.Message.ToString());
            }
        }

    }

 

主函数源码:

在控制台界面上输入run会看到某个等待着的线程被开启:

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("**********************************");
            Console.WriteLine("请输入\"run\"开启正在等待着的线程...");
            Console.WriteLine("********************************\r\n");

            AutoResetEventTest test = new AutoResetEventTest();

            test.CreateThreads(10);

            while (true)
            {
                string input = Console.ReadLine();
                if (input.Trim().ToLower() == "run")
                {
                    Console.WriteLine("WaitOne等待着的某个线程开启运行...");
                    test.Set();
                }
            }

        }
    }

 

运行结果:

当输入一次run时,显示如下:

由于初始化AutoResetEvent 事件为false,则该事件处于非终止状态,故所有等待着的线程在没有Set信号到来时,都将暂停运行,当输入一次run,调用AutoResetEvent 的Set方法,将会随机开启某一个正在等待着的线程,当该等待着的线程被释放,则AutoResetEvent 自动的变为非终止状态,其余的等待线程想要开启就必须等待再一次Set信号。

 

当输入多次run时,显示结果如下:

每输入一次run都会调用AutoResetEvent 事件的Set方法,将会随机开启某一个正在等待着的线程,当这个线程被释放后,则AutoResetEvent  事件会自动的置为非终止状态,那么刚刚被开启的线程将会再次等待,直到等待下一次Set信号将它开启。

假如我们初始化将AutoResetEvent 事件设置为true,则在控制台下会看到如下结果:

这是因为初始化将AutoResetEvent 事件设置为true,则它会处于终止状态,那么会初次开启某个线程,当这个等待着的线程被释放时,则会自动将AutoResetEvent 设置成非终止状态,直到有Set信号给某个等待着的线程,才会开启这个等待着的线程。

 

如下:

再一次输入run,

 

调用AutoResetEvent  的Set方法,将会随机的开启某一个正在等待着的线程,线程释放完毕后会自动将AutoResetEvent 置为非终止状态,所以每当run一次只能看到一次随机等待的线程在跑

 

 

posted @ 2014-11-06 09:38  PS-Jerry  阅读(2349)  评论(0编辑  收藏  举报