//本文演示了ManualResetEvent 类的非静态set()、Reset()、WaitOne()和
//WaitHandle类的静态方法WaitAllWaitAll()
//它们用于线程间的同步控制。
//实现了如下功能:线程1(定时控制)通知线程2和线程3采集数据
//线程2和3数据采集完了,各自通知线程1情况。
//那么线程1收到了两个线程的通知,则进行下一轮采集
static void Main(string[] args)
         {
             const int numberOfFiles=2;
             Console.WriteLine("Press any key to start");
             Console.ReadKey();
             var cancelToken = new CancellationTokenSource();
             var random = new Random();
             Console.WriteLine("Task started, press any key to stop...");
     
             var manualResetEvent1 = new ManualResetEvent(false);
             var manualResetEvent2 = new ManualResetEvent(false);
             ManualResetEvent [] manualEvents = new ManualResetEvent[numberOfFiles];
             for (int i = 0; i < numberOfFiles; i++)
             {
                 manualEvents[i] = new ManualResetEvent(false);
             }
             bool reached = true;
            //线程1
             Task.Factory.StartNew(() =>
             {
                while (!cancelToken.IsCancellationRequested)
                 {
                    if (reached)
                     {
                         manualResetEvent1.Set();
                         manualResetEvent2.Set();
                         Console.WriteLine("Start new turn-----------------------");
                     }
                    
                     Thread.Sleep(300);
                     reached = WaitHandle.WaitAll(manualEvents,400,false);
                     manualEvents[0].Reset();
                     manualEvents[1].Reset();
                 }
             });
            //线程2
             Task.Factory.StartNew(() =>
             {
                 var num = random.Next(10, 15);
                
                 while (!cancelToken.IsCancellationRequested)
                 {
                     manualResetEvent1.WaitOne();
                     Thread.Sleep(200);
                     num = random.Next(10, 15);
                     Console.WriteLine($"Task1 is running, this is number {num} ");
                    
                     manualResetEvent1.Reset();
                     manualEvents[0].Set();
                 }
             });
            //线程3
             Task.Factory.StartNew(() =>
             {
                 var num = random.Next(5, 10);
                 
                 while (!cancelToken.IsCancellationRequested)
                 {
                     manualResetEvent2.WaitOne();
                     Thread.Sleep(100);
                     num = random.Next(5, 10);
                     Console.WriteLine($"Task2 is running, this is number {num}");
                     manualResetEvent2.Reset();
                     manualEvents[1].Set();
                 }
             });
             Console.ReadLine();
             cancelToken.Cancel();
             Console.WriteLine("task cancelled");
             Console.ReadLine();
         }