AutoResetEvent and ManualResetEvent 的初始化
两者初始化时可以接受一个 bool 类型值作为构造函数的参数.
false: 无信号 (非终止状态)
true: 有信号 (终止状态)
///
/// 注释为程序执行流
///
public partial class Form1 : Form
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(this.Fun1);
t1.Start();
// 阻塞当前线程,转而执行t1线程
Thread.Sleep(3000);
// 3秒后给调用set()给出信号,当前线程后面没有代码了,程序转而执行t1线程
autoResetEvent.Set();
}
void Fun1()
{
// 由于信号初始化时的状态时false,waitone()会阻塞当前线程,等待信号
autoResetEvent.WaitOne();
MessageBox.Show("t1 step1 end!");
}
// 结论
// 此程序3秒后弹出 "t1 step1 end!"
// 如果初始化 autoResetEvent 时使用 true 参数,程序会立刻弹出 "t1 step1 end!"
// 在有信号的状态下,.WaitOne()不会起作用,切记!
}
AutoResetEvent and ManualResetEvent 的区别:
public partial class Form1 : Form
{
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
//ManualResetEvent autoResetEvent = new ManualResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(this.Fun1);
t1.Start();
Thread t2 = new Thread(this.Fun2);
t2.Start();
Thread.Sleep(3000);
autoResetEvent.Set();
}
void Fun1()
{
autoResetEvent.WaitOne();
MessageBox.Show("t1 step1 end!");
}
void Fun2()
{
autoResetEvent.WaitOne();
MessageBox.Show("t2 step1 end!");
}
// 结论1
// 此程序3秒后,要么弹出 "t1 step1 end!",要么弹出 "t2 step1 end!"
// 也就是说,其中有一个线程是永远也等不到信号的
// 结论2
// 如果交换注释行,则会同时弹出 "t1 step1 end!" 和 "t2 step1 end!"
// AutoResetEvent 只会给一个线程发送信号
// ManualResetEvent 会给多个线程发送信号
}
ManualResetEvent 的 Set() 与 Reset()
public partial class Form1 : Form
{
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
private void button1_Click(object sender, EventArgs e)
{
Thread t1 = new Thread(this.Fun1);
t1.Start();
Thread t2 = new Thread(this.Fun2);
t2.Start();
Thread.Sleep(3000);
manualResetEvent.Set();
//autoResetEvent.Reset();
}
void Fun1()
{
manualResetEvent.WaitOne();
MessageBox.Show("t1 step1 end!");
// 睡1秒,等待主线程的Reset()
Thread.Sleep(1000);
manualResetEvent.WaitOne();
MessageBox.Show("t1 step2 end!");
}
void Fun2()
{
manualResetEvent.WaitOne();
MessageBox.Show("t2 step1 end!");
// 睡1秒,等待主线程的Reset()
Thread.Sleep(1000);
manualResetEvent.WaitOne();
MessageBox.Show("t2 step2 end!");
}
// 结论1
// 程序3秒后会弹出 "t1 step1 end!" 和 "t2 step1 end!"
// 接着1秒后会弹出 "t1 step2 end!" 和 "t2 step2 end!"
// 由于 ManualResetEvent 在Set()后,并不会自动把线程状态变为false,因此后2步的waitone()不会起作用
// 如果取消注释行,永远也不会弹出 "t1 step2 end!" 和 "t2 step2 end!",除非再次进行Set();
// 结论2
// AutoResetEvent在Set()后,会将线程状态自动置为false,ManualResetEvent在Set()后就变为ture了
// ManualResetEvent必须手动Reset()后才能变为false,这也就是他们为什么一个是Auto,一个是Manual
}
结论
这些信号灯是以自身的状态来控制所有的线程运行方式,同步,等待等等.