这说明tWork开始在autoResetEvent上等待任何其他地方给它的信号。信号来了,则tWork开始继续工作,否则就一直等着(即阻滞)。接下来看看主线程中的这句代码(本例中即UI线程,它相对于线程tWork来说,就是一个“另外的线程”):
主线程通过上面这句代码向在autoResetEvent上等待的线程tWork上下文发送信号,即将tWork的阻滞状态设置为true。tWork接收到这个信号后,开始继续工作。 这个例子相当简单,但是已经完整说明了信号机制的工作原理。 AutoResetEvent和ManualResetEvent的区别是:前者在发送信号完毕后(即调用Set方法),会自动将自己的阻滞状态设置为false,而后者则需要进行手动设定。通过一个例子来说明这种区别,如下所示:
- AutoResetEvent autoResetEvent = new AutoResetEvent(false);
-
- private void buttonStartAThread_Click(object sender, EventArgs e)
- {
- StartThread1();
- StartThread2();
- }
-
- private void StartThread1()
- {
- Thread tWork1 = new Thread(() =>
- {
- label1.Text = "线程1启动..." + Environment.NewLine;
- label1.Text += "开始处理一些实际的工作" + Environment.NewLine;
- //省略工作代码
- label1.Text += "我开始等待别的线程给我信号,才愿意继续下去" +
- Environment.NewLine;
- autoResetEvent.WaitOne();
- label1.Text += "我继续做一些工作,然后结束了!";
- //省略工作代码
- });
- tWork1.IsBackground = true;
- tWork1.Start();
- }
-
- private void StartThread2()
- {
- Thread tWork2 = new Thread(() =>
- {
- label2.Text = "线程2启动..." + Environment.NewLine;
- label2.Text += "开始处理一些实际的工作" + Environment.NewLine;
- //省略工作代码
- label2.Text += "我开始等待别的线程给我信号,才愿意继续下去" +
- Environment.NewLine;
- autoResetEvent.WaitOne();
- label2.Text += "我继续做一些工作,然后结束了!";
- //省略工作代码
- });
- tWork2.IsBackground = true;
- tWork2.Start();
- }
-
- private void buttonSet_Click(object sender, EventArgs e)
- {
- //给在autoResetEvent上等待的线程一个信号
- autoResetEvent.Set();
- }
|
这个例子的本意是要让新起的两个工作线程tWork1和tWork2都阻滞,直到收到主线程的信号再继续工作。而程序运行的结果是,只有一个工作线程继续工作,另外一个工作线程则继续保持阻滞状态。我想可能大家都已经猜到原因了,即AutoResetEvent发送信号完毕就在内核中自动将自己的状态设置回false了,所以另外一个工作线程相当于根本没有收到主线程的信号。