C#理解AutoResetEvent和ManualResetEvent

    当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,能够理解这两个类能够经过设置信号来让线程停下来或让线程从新启动,其实与操做系统里的信号量很类似(汗,考完考试已经有点忘记了)。下面上代码编程

    class Program
    {
        const int count = 10;
        //赋值为false也就是没有信号
        static AutoResetEvent myResetEvent = new AutoResetEvent(false);
        static int number;
        static void Main(string[] args)
        {
            Thread thread = new Thread(funThread);
            thread.Name = "QQ";
            thread.Start();
            for (int i = 1; i < count; i++)
            {
                Console.WriteLine("first number: {0}",i);
                number = i;
                //这里是设置为有信号
                myResetEvent.Set();
                Thread.Sleep(2000);
            }
            thread.Abort();
        }

        static void funThread()
        {
            while (true)
            {
                //执行到这个地方时,会等待set调用后改变了信号才接着执行
                myResetEvent.WaitOne();
                Console.WriteLine("end {0} number: {1}", Thread.CurrentThread.Name, number);
            }
        }

    }

输出结果为多线程

first number:1函数

end QQ number:1spa

first number:2操作系统

end QQ number:3线程

.....code

   简单来讲只有调用Set()方法后才能执行WaitOne()后面的代码,AutoResetEvent和ManualResetEvent分别都有Set()改变为有信号 ,Reset()改变为无信号,WaitOne()将会阻塞当前调用的线程,直到有信号为止,即执行了Set()方法,WaitOne()方法还能够带指定时间的参数。对象

   理解了AutoResetEvent后再理解ManualResetEvent也就不难了,AutoResetEvent与ManualResetEvent的区别是,AutoResetEvent.WaitOne()会自动改变事件对象的状态,即AutoResetEvent.WaitOne()每执行一次,事件的状态就改变一次,也就是从无信号变为有信号,或从有信号变为无信号。而ManualResetEvent则是调用Set()方法后其信号量不会自动改变,除非再设置Reset()方法。blog

   在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类常常用到, 他们的用法很相似,但也有区别。Set方法将信号置为发送状态,Reset方法将信号置为不发送状态,WaitOne等待信号的发送。能够经过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态。若是某个线程调用WaitOne方法,则当信号处于发送状态时,该线程会获得信号, 继续向下执行。其区别就在调用后,AutoResetEvent.WaitOne()每次只容许一个线程进入,当某个线程获得信号后,AutoResetEvent会自动又将信号置为不发送状态,则其余调用WaitOne的线程只有继续等待.也就是说,AutoResetEvent一次只唤醒一个线程;而ManualResetEvent则能够唤醒多个线程,由于当某个线程调用了ManualResetEvent.Set()方法后,其余调用WaitOne的线程得到信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就能够同时唤醒多个线程继续执行。事件

相关文章
相关标签/搜索