问题抽象:当某个操作的执行必须依赖于另一个操作的完成时,需要有个机制来保证这种先后关系。
线程通信方案:ManualResetEventSlim、ManualResetEvent、AutoResetEvent
方案特性:提供线程通知的能力,没有接到通知前,线程必须等待,有先后顺序。

1、ManualResetEvent类
     对象有两种信号量状态True和False。构造函数设置初始状态。简单来说,
     ◆ 如果构造函数由true创建,则第一次WaitOne()不会阻止线程的执行,而是等待Reset后的第二次WaitOne()才阻止线程执行。
     ◆ 如果构造函数有false创建,则WaitOne()必须等待Set()才能往下执行。
  一句话总结就是:是否忽略第一次阻塞。
  方法如下:
       ◆ WaitOne:该方法用于阻塞线程,默认是无限期的阻塞,支持设置等待时间,如果超时就放弃阻塞,不等了,继续往下执行;
       ◆ Set:手动修改信号量为True,也就是恢复线程执行;
       ◆ ReSet:重置状态; 重置后,又能WaitOne()啦

using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        //一开始设置为false才会等待收到信号才执行
        static ManualResetEvent mr = new ManualResetEvent(false);
        public static void Main()
        {
            Thread t = new Thread(Run);
            //启动辅助线程
            t.Start();
            //等待辅助线程执行完毕之后,主线程才继续执行
            Console.WriteLine("主线程一边做自己的事,一边等辅助线程执行!" + DateTime.Now.ToString("mm:ss"));
            mr.WaitOne();
            Console.WriteLine("收到信号,主线程继续执行" + DateTime.Now.ToString("mm:ss"));
            Console.ReadKey();
        }

        static void Run()
        {
            //模拟长时间任务
            Thread.Sleep(3000);
            Console.WriteLine("辅助线程长时间任务完成!" + DateTime.Now.ToString("mm:ss"));
            mr.Set();
        }
    }
}
Program

相关文章: