public static double RangeParTask3(double[] data, int miss, int size, out long elapsed)
        {
            double result = 0;
            bool   isOdd  = size % 2 != 0;
            int    j      = 0;
            int    n      = size;

            if (n % 2 == 0)
            {
                n /= 2;
            }
            else
            {
                n = (n + 1) / 2;
            }

            Task[] tasks1 = new Task[n];

            Stopwatch timer = Stopwatch.StartNew();
            //task pertama perlakuan khusus
            Task taskCuk = Task.Factory.StartNew(() =>
            {
                j = 0;
                for (int i = 0; i < n; i++)
                {
                    tasks1[i] = Task.Factory.StartNew((Object obj) =>
                    {
                        HelperRangeData check = obj as HelperRangeData;
                        if (check == null)
                        {
                            return;
                        }
                        check.ThreadNum = Thread.CurrentThread.ManagedThreadId;
                        if (check.Max < check.Min)
                        {
                            double tmp = check.Max;
                            check.Max  = check.Min;
                            check.Min  = tmp;
                        }
                    },
                                                      new HelperRangeData()
                    {
                        Index        = i,
                        CreationTime = DateTime.Now.Ticks,
                        Max          = (n % 2 == 0 || j != size - 1) ? data[j++] : data[j],
                        Min          = (n % 2 == 0 || j != size - 1) ? data[j++] : data[j]
                    }, TaskCreationOptions.AttachedToParent);
                }
            });

            taskCuk.Wait();
            //right after taskCuk done, start new task
            Task taskMenehCuk = Task.Factory.StartNew(() =>
            {
                int ii     = 0;
                bool first = true;
                while (n > 1)
                {
                    List <Task> tasks2      = new List <Task>();
                    List <Task> taskToCheck = new List <Task>();
                    if (first)
                    {
                        for (int xx = 0; xx < tasks1.Length; xx++)
                        {
                            taskToCheck.Add(tasks1[xx]);
                        }
                        first = false;
                    }
                    else
                    {
                        for (int xx = 0; xx < tasks2.Count; xx++)
                        {
                            taskToCheck.Add(tasks2[xx]);
                        }
                    }
                    bool thisIsOdd = n % 2 != 0;
                    int n_before   = n;
                    if (!thisIsOdd)
                    {
                        n /= 2;
                    }
                    else
                    {
                        n = (n + 1) / 2;
                    }
                    ii = 0;
                    for (int k = 0; k < n; k++)
                    {
                        Task some = Task.Factory.StartNew((object sender) =>
                        {
                            HelperRangeData check = sender as HelperRangeData;
                            if (check == null)
                            {
                                return;
                            }

                            Task grandChild1 = Task.Factory.StartNew((object obj) =>
                            {
                                //cek ganjil/genap
                                obj = (!thisIsOdd || ii != n_before - 1) ?
                                      taskToCheck[ii++].AsyncState as HelperRangeData : tasks1[ii].AsyncState as HelperRangeData;
                            }, new HelperRangeData(), TaskCreationOptions.AttachedToParent);
                            Task grandChild2 = Task.Factory.StartNew((object obj) =>
                            {
                                obj = (!thisIsOdd || ii != n_before - 1) ?
                                      taskToCheck[ii++].AsyncState as HelperRangeData : tasks1[ii].AsyncState as HelperRangeData;
                            }, new HelperRangeData(), TaskCreationOptions.AttachedToParent);

                            check.ThreadNum         = Thread.CurrentThread.ManagedThreadId;
                            HelperRangeData helper1 = grandChild1.AsyncState as HelperRangeData;
                            HelperRangeData helper2 = grandChild2.AsyncState as HelperRangeData;
                            check.Max = (helper1.Max > helper2.Max) ? helper1.Max : helper2.Max;
                            check.Min = (helper1.Min < helper2.Min) ? helper1.Min : helper2.Min;
                        },
                                                          new HelperRangeData()
                        {
                            Index        = k,
                            CreationTime = DateTime.Now.Ticks,
                        }, TaskCreationOptions.AttachedToParent);

                        tasks2.Add(some);
                    }
                }
            });

            taskMenehCuk.Wait();
            timer.Stop();
            //result = max - min;
            elapsed = timer.ElapsedTicks;
            return(result);
        }
        public static double RangeParTask2(double[] data, int miss, int size, out long elapsed)
        {
            bool isOdd = size % 2 != 0;
            int  j     = 0;
            int  n     = size;

            if (n % 2 == 0)
            {
                n /= 2;
            }
            else
            {
                n = (n + 1) / 2;
            }

            Task[] tasks1 = new Task[n];

            Stopwatch timer = Stopwatch.StartNew();

            for (int i = 0; i < n; i++)
            {
                tasks1[i] = Task.Factory.StartNew((Object obj) =>
                {
                    HelperRangeData check = obj as HelperRangeData;
                    if (check == null)
                    {
                        return;
                    }
                    check.ThreadNum = Thread.CurrentThread.ManagedThreadId;
                    if (check.Max < check.Min)
                    {
                        double tmp = check.Max;
                        check.Max  = check.Min;
                        check.Min  = tmp;
                    }
                },
                                                  new HelperRangeData()
                {
                    Index        = i,
                    CreationTime = DateTime.Now.Ticks,
                    Max          = ((!isOdd && j < size) || j != size - 1) ? data[j++] : data[j],
                    Min          = ((!isOdd && j < size) || j != size - 1) ? data[j++] : data[j]
                });
            }
            Task.WaitAll(tasks1);
            double max, min;

            max = double.MinValue;
            min = double.MaxValue;
            for (int i = 0; i < tasks1.Length; i++)
            {
                var check = tasks1[i].AsyncState as HelperRangeData;
                Debug.WriteLine("id: " + check.Index + " on thread #" + check.ThreadNum + " ");
                max = check.Max > max ? check.Max : max;
                min = check.Min < min ? check.Min : min;
            }
            Debug.WriteLine("");
            timer.Stop();
            elapsed = timer.ElapsedTicks;
            return(max - min);
        }