关于AutoResetEvent和ManualResetEvent

两者都继承自EventWaitHandle,自然也就有点相通的地方了

简单来说,无论是AutoResetEvent还是ManualResetEvent,都是通过发出Signal信号来通知正在等待的线程的。有人可能要问,为什么要用它们来做这些事情, 嗯, 是这样的, 在.Net的多线程环境中,资源的共享变得尤其重要,如果没有一个有效的方法来维护资源的原子状态,在抢占式的CPU环境中,所有的事情都会变得无法控制。AutoResetEvent和ManualResetEvent正是用来保证资源的原子性的一个手段的两个方面。正如它们的名字一样, AutoResetEvent会在每次被Signal了之后自动(Automatically)转变为UnSignal,而ManualResetEvent则不然,无论是Signal还是UnSignal都需要人为的介入去改变它的状态。

在AutoResetEvent的构造函数中,有唯一的一个参数,initialState,Boolean类型,它用来初始化AutoResetEvent的Signal状态,True为Signal,False为UnSignal,这与ManualResetEvent的构造函数是一样的。

AutoResetEvent或ManualResetEvent都是通过Set()/Reset()两个方法来Signal/UnSignal信号,通过调用WaitOne方法来阻塞当前线程,当收到Signal后就继续往下执行。上面提到过,AutoResetEvent会自动把信号复位(自动调用Reset),而ManualResetEvent则需要人手复位,也就是说,AutoResetEvent每次只允许一条线程进入,其它所有需要访问该资源的线程都要排队等候,直到AutoResetEvent得到信号后,下一条线程开始工作,同时AutoResetEvent又会自动复位信号,让其他线程继续等候;而ManualResetEvent则每次可以唤醒多个线程,因为当ManualResetEvent得到信号后,其他调用WaitOne方法的线程都将得到信号得以继续往下执行,ManualResetEvent不会自动复位信号,换句话说,除非手动的调用了ManualResetEvent.Reset方法,否则ManualResetEvent一直保持有信号状态,这样就可以同时唤醒多条线程了

作为一个示例,下面的DemoCode一开始就运行一条子线程,然后用AutoResetEvent/ManualResetEvent来控制MessageBox的输出流程。

如果在Foo和button1_Click里面用AutoResetEvent,一开始得到"1",然后每点击一次Button1得到"2"和"3"。

如果用ManualResetEvent,一开始得到"1",然后只需点击Button1一次,就可以得到"2"和"3"了

public partial class Form1 : Form
{
    protected AutoResetEvent autoEvent;
    protected ManualResetEvent manualEvent;
    public Form1()
    {
        InitializeComponent();
        autoEvent = new AutoResetEvent(false);
        manualEvent = new ManualResetEvent(false);

        Thread aThread = new Thread(new ParameterizedThreadStart(Foo));
        aThread.Name = "aThread";
        aThread.IsBackground = true;
        aThread.Start();
    }

    private void Foo(object state)
    {
        MessageBox.Show("1");
        autoEvent.WaitOne();
        // manualEvent.WaitOne();
        MessageBox.Show("2");
        //manualEvent.Reset();
        autoEvent.WaitOne();
        //  manualEvent.WaitOne();
        MessageBox.Show("3");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        autoEvent.Set();
        // manualEvent.Set();
    }

}

魔兽就是毒瘤,大家千万不要玩。
原文地址:https://www.cnblogs.com/tracy/p/1860523.html