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:1

first number:2

end QQ number:3

.....

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

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

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

时间: 2024-09-30 19:20:18

C#深入理解AutoResetEvent和ManualResetEvent的相关文章

AutoResetEvent和ManualResetEvent理解

AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandleAPI类似,使用中还是有区别的. 之前每次需要使用的时候,都去找他们之间的区别.虽然当时是明白了,但没有深入理解透彻,过几天又忘记了.等到下次需要使用的时候又要重新去理解这2个类. 今天再次遇到他们,写下这篇随笔..加深理解印象.到了下次再用到不用再去纠结区别了. 1.构造函数参数 var manualResetEventWaitHandle = new ManualRe

个人对AutoResetEvent和ManualResetEvent的理解

一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非终止,乱七八糟的.在这里,我们以一种通俗易懂的概念来说明. 二.比喻 如果把每个线程比作一辆汽车的话,AutoResetEvent和ManualResetEvent就是公路上的收费站. 其中: Reset 关闭收费站车闸禁止通行(拦截车辆才好收费啊): WaitOne 收费员等待下一辆车辆过来(然后

个人对AutoResetEvent和ManualResetEvent的理解(转载)

仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非终止,乱七八糟的.在这里,我们以一种通俗易懂的概念来说明. 二.比喻 如果把每个线程比作一辆汽车的话,AutoResetEvent和ManualResetEvent就是公路上的收费站. 其中: Reset 关闭收费站车闸禁止通行(拦截车辆才好收费啊): WaitO

AutoResetEvent和ManualResetEvent理解 z

AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去深入思考记忆,过几天又忘记了.到下次需要使用的时候又要重新去理解这2个类. 今天再次遇到他们,写下这篇随笔..加深理解印象.以后不用去纠结他们了. 1.构造函数参数 var manualResetEventWaitHandle = new ManualResetEvent(true); var au

[转]个人对AutoResetEvent和ManualResetEvent的理解

仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非终止,乱七八糟的.在这里,我们以一种通俗易懂的概念来说明. 二.比喻 如果把每个线程比作一辆汽车的话,AutoResetEvent和ManualResetEvent就是公路上的收费站. 其中: Reset 关闭收费站车闸禁止通行(拦截车辆才好收费啊): WaitO

C#AutoResetEvent和ManualResetEvent的区别

一:终止状态和非终止状态 首先说说线程的终止状态和非终止状态.AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态.true表示终止状态(个人理解也就是可运行状态,根据理解应该是该线程的阻塞终止了),false表示非终止状态. AutoResetEvent _autoResetEvent = new AutoResetEvent(false); private void BT_Temp_Click(object sender

服务总结 -多线程 - 线程同步(AutoResetEvent与ManualResetEvent)

前言 在我们编写多线程程序时,会遇到这样一个问题:在一个线程处理的过程中,需要等待另一个线程处理的结果才能继续往下执行.比如:有两个线程,一个用来接收Socket数据,另一个用来处理Socket数据,而处理Socket数据的那个线程需要在接收到Socket数据后才能处理运行,就要等待接收线程接收数据.那么处理线程如何等待,接收线程又如何通知处理线程呢? 其中一个比较好的方式就是使用AutoResetEvent/ManualResetEvent 1. AutoResetEvent/ManualRe

C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent

最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading.WaitHandle.WaitOne .System.Threading.WaitHandle.WaitAny和System.Threading.WaitHandle.WaitAll ,下面我们一最初学者的角度来看,多线程之间的同步. 假设有这样的一个场

AutoResetEvent和ManualResetEvent对比

一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非终止,乱七八糟的.在这里,我们以一种通俗易懂的概念来说明. 二.比喻 如果把每个线程比作一辆汽车的话,AutoResetEvent和ManualResetEvent就是公路上的收费站. 其中: Reset 关闭收费站车闸禁止通行(拦截车辆才好收费啊): WaitOne 收费员等待下一辆车辆过来(然后