static void worker(EventSignaller signal, CountdownEvent countdown, int workerNumber)
        {
            print($"Worker {workerNumber} is waiting for signal.");
            signal.Wait();
            int delay = randomDelayMilliseconds();

            print($"Worker {workerNumber} got signal, now sleeping for {delay}");
            Thread.Sleep(delay);
            print($"Worker {workerNumber} finished work.");
            countdown.Signal();
        }
        static void Main()
        {
            print("Main thread is starting the workers.");
            int numWorkers = 10;
            var signal     = new EventSignaller();
            var countdown  = new CountdownEvent(numWorkers);

            for (int i = 0; i < numWorkers; ++i)
            {
                int n = i;     // Prevent modified closure.
                Task.Run(() => worker(signal, countdown, n));
            }
            print("Main thread is waiting for a five seconds.");
            Thread.Sleep(5000);
            print("Main thread is signalling all the workers to start.");
            signal.Signal();
            print("Main thread is waiting for all the workers to finish.");
            countdown.Wait();
            print("Main thread finished waiting for all the workers to complete.");
        }