ManualResetEvent和AutoResetEvent的区别

相同部分

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

一般初始化为false ,即线程阻塞,调用 waitHandler.WaitOne();就卡住了

2.Set()方法,设置线程为可运行状态,即不卡了,waitHandler.WaitOne();下面的方法就可以往下走了

3.ReSet() 设置为卡的状态

不同部分

举例子说明

ManualResetEvent waitHandler = new ManualResetEvent(false);//false 即非终止,未触发。
new Thread(() =>
{
waitHandler.WaitOne(); //阻塞当前线程,等待底层内核对象收到信号。
Console.WriteLine("接收到信号,开始处理。");


}).Start();

new Thread(() =>
{
waitHandler.WaitOne(); //阻塞当前线程,等待底层内核对象收到信号。
Console.WriteLine("接收到信号,开始处理。");


}).Start();

new Thread(() =>
{
Console.WriteLine("发信号");
waitHandler.Set(); //向内核对象发送信号。设置事件对象为非终止状态、false,解除阻塞。

}).Start();
Console.ReadLine();

若把上面的换成AutoResetEvent

从上面运行结果可以清晰的看到

在ManualResetEvent 时,set之后两个线程都为可运行状态

在AutoResetEvent   时,只有一个线程可运行,另一个还在卡

因此总结ManualResetEvent和AutoResetEvent的一个重要区别:

可以想象ManualResetEvent这个对象内部有一个Boolean类型的属性IsRelease来控制是否要阻塞当前线程。这个属性我们在初始化的时候可以设置它,如ManualResetEvent event=new ManualResetEvent(false);这就表明默认的属性是要阻塞当前线程

 manual的话肯定会给线程1和线程2都发送一个信号,而auto只会随机给其中一个发送信号。

        为什么一个叫manual而一个叫auto呢?我想这是很多人的疑问,现在我们就来看这个问题。

       刚才_manualResetEvent .Set();的这句话我想大家都明白了,可以看做将IsRelease的属性设置为true.线程1中

 _manualResetEvent.WaitOne();接收到信号后不再阻塞线程1。在此之后的整个过程中IsRelease的值都是true.如果

想将IsRelease的值回复成false,就必须再调用_manualResetEvent.Reset()的方法。

    如果是_autoResetEvent.set(),那么_autoResetEvent.WaitOne()后会自动将IsRelease的值自动设置为false.

这就是为什么一个叫auto,一个叫manual.

猜你喜欢

转载自www.cnblogs.com/baihong/p/9234715.html
今日推荐