AutoResetEvent/ManualResetEvent 都是继承自 EventWaitHandle ,EventWaitHandle继承自WaitHandle.this
在讨论这个问题以前,咱们先了解这样一种观点,线程之间的通讯是经过发信号来进行沟通的。(这不是废话)spa
先来讨论ManualResetEvent,讨论过程当中我会穿插一些AutoResetEvent的内容,来作对比:线程
ManualResetEvent均可以阻塞一个或多个线程,直到收到一个信号告诉ManualResetEvent不要再阻塞当前的线程。对象
能够想象ManualResetEvent这个对象内部有一个Boolean类型的属性IsRelease来控制是否要阻塞当前线程。这个属性咱们在初始化的时候能够设置它,如ManualResetEvent event=new ManualResetEvent(false);这就代表默认的属性是要阻塞当前线程。继承
代码举例:it
ManualResetEvent _manualResetEvent = new ManualResetEvent(false);event
private void BT_Temp_Click(object sender, RoutedEventArgs e)
{
Thread t1 = new Thread(this.Thread1Foo);
t1.Start(); //启动线程1
Thread t2 = new Thread(this.Thread2Foo);
t2.Start(); //启动线程2
Thread.Sleep(3000); //睡眠当前主线程,即调用BT_Temp_Click的线程
_manualResetEvent .Set(); //想象成将IsRelease设为True
}object
void Thread1Foo()
{
_manualResetEvent .WaitOne(); 程序
//阻塞线程1,直到主线程发信号给线程1,告知_menuResetEvent你的IsRelease属性已经为true,方法
//这时再也不阻塞线程1,程序继续往下跑
MessageBox.Show("t1 end");
}
void Thread2Foo()
{
_manualResetEvent .WaitOne();
//阻塞线程2,直到主线程发信号给线程1,告知_menuResetEvent你的IsRelease属性已经为true,
//这时再也不阻塞线程2,程序继续往下跑
MessageBox.Show("t2 end");
}
注意这里ManualResetEvent和AutoResetEvent的一个重要区别:
1.manual的话确定会给线程1和线程2都发送一个信号,而auto只会随机给其中一个发送信号,也就是只有一方能够继续行动。
为何一个叫manual而一个叫auto呢?我想这是不少人的疑问,如今咱们就来看这个问题。
2.刚才_manualResetEvent .Set();的这句话我想你们都明白了,能够看作将IsRelease的属性设置为true.线程1中
_manualResetEvent.WaitOne();接收到信号后再也不阻塞线程1。在此以后的整个过程当中IsRelease的值都是true.若是
想将IsRelease的值回复成false,就必须再调用_manualResetEvent.Reset()的方法。