相同部分
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.