Event Sample in C#

This blog shows on how to use an event sample in c#

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            const int taskCount = 4;

            var manEvnts = new ManualResetEventSlim[taskCount];
            var waitHndls = new WaitHandle[taskCount];
            var calcs = new Calculator[taskCount];

            TaskFactory taskFactory = new TaskFactory();
            for (int i = 0; i < taskCount; i++)
            {
                manEvnts[i] = new ManualResetEventSlim(false);
                waitHndls[i] = manEvnts[i].WaitHandle;
                calcs[i] = new Calculator(manEvnts[i]);
                taskFactory.StartNew(calcs[i].Calculation, Tuple.Create(i + 1, i + 3));
            }
            for (int i = 0; i < taskCount; i++)
            {
                int index = WaitHandle.WaitAny(waitHndls);
                if (index == WaitHandle.WaitTimeout)
                {
                    Console.WriteLine("Timeout!!");
                }
                else
                {
                    manEvnts[index].Reset();
                    Console.WriteLine("finished task for {0}, result: {1}",
                                      index, calcs[index].Result);
                }
            }

        }
    }

    public class Calculator
    {
        private ManualResetEventSlim mEvent;
        private CountdownEvent cEvent;
        public int Result { get; private set; }
        public Calculator(ManualResetEventSlim ev)
        {
            this.mEvent = ev;
        }
        public Calculator(CountdownEvent ev)
        {
            this.cEvent = ev;
        }

        public void Calculation(object obj)
        {
            Tuple<int, int> data = (Tuple<int, int>)obj;
            Console.WriteLine("Task {0} starts calculation", Task.CurrentId);
            Thread.Sleep(new Random().Next(3000));
            Result = data.Item1 + data.Item2;
            Console.WriteLine("Task {0} is ready", Task.CurrentId);
            mEvent.Set();
        }
    }
}