Exemplo n.º 1
0
        // *********
        protected virtual void OnAllTasksCompleted(CompletedEventArgs e)
        {
            EventHandler <CompletedEventArgs> handler = AllTasksCompleted;

            if (handler != null)
            {
                handler(this, e);
            }
        }
Exemplo n.º 2
0
        /*
         * Bounding is also used to introduce artificial latency into the WithoutBlocking sample.
         * One of the major differences between WithoutBlocking and WithBlocking are the TryAdd and TryTake statements.
         * Examination of the parameters reveals timeout values in milliseconds or in a defined TimeSpan class.
         * WithoutBlocking Tasks, block for small increments of time before continuing execution.
         * The sample code utilizes seconds or half seconds, but given that a Timespan can be a small interval, a developer is not constrained to milliseconds.
         * Because a method can return before the timeout interval, WithoutBlocking also excludes the try/catch code.
         * This is an interesting sample to tinker with.
         * Changing the Sleep values in Task1 and Task2 has some interesting effects and really demonstrates shifting bottlenecks in code.
         */

        public void WithoutBlocking(int boundvalue, int stage1timeout, int stage2timeout, CancellationTokenSource tokenSource)
        {
            int[] items     = { 1, 2, 3, 4, 5, 6, 7, 8 };
            var   startTime = DateTime.Now;


            message += "Producer...Starting...WithoutBlocking" + Environment.NewLine;

            var stage1 = new BlockingCollection <int>();
            var stage2 = new BlockingCollection <int>(boundvalue);           //Required to force the TryAdd delay

            //Pulls numbers from the array
            var task0 = Task.Factory.StartNew(() =>
            {
                foreach (int i in items)
                {
                    if (tokenSource.IsCancellationRequested)
                    {
                        break;
                    }

                    stage1.Add(i);
                    message += ("T" + Thread.CurrentThread.ManagedThreadId.ToString()
                                + "Producer - Add:" + i.ToString() + " Count=" + stage1.Count.ToString() + Environment.NewLine);
                }

                if (tokenSource.IsCancellationRequested)
                {
                    message += "Producer - Cancellation requested, exiting..." + Environment.NewLine;
                }
                else
                {
                    message += "Producer - Loaded all items into stage 1..." + Environment.NewLine;
                    stage1.CompleteAdding();
                }
            }, tokenSource.Token);

            //Reads and passes data onto next stage
            var task1 = Task.Factory.StartNew(() =>
            {
                int i = -1;
                while (!stage1.IsCompleted)
                {
                    if (tokenSource.IsCancellationRequested)
                    {
                        break;
                    }

                    if (stage1.TryTake(out i, stage1timeout))
                    {
                        message += ("T" + Thread.CurrentThread.ManagedThreadId.ToString()
                                    + " Consumer1 - Stage 1 Process: " + i.ToString() + " elapsed " + DateTime.Now.Subtract(startTime).TotalSeconds.ToString() + Environment.NewLine);

                        while (!stage2.TryAdd(i, new TimeSpan(0, 0, 0, 0, stage2timeout)))
                        {
                            message += ("T" + Thread.CurrentThread.ManagedThreadId.ToString()
                                        + " Consumer1 - Attempt to add " + i.ToString() + " expired elapsed " + DateTime.Now.Subtract(startTime).TotalSeconds.ToString() + Environment.NewLine);
                        }

                        //Pause X miliseconds simulating work
                        //change to as high as 2000 and low as 100
                        //to see impact
                        Thread.Sleep(new TimeSpan(0, 0, 0, 0, 2000));
                    }
                    else
                    {
                        message += ("T" + Thread.CurrentThread.ManagedThreadId.ToString()
                                    + " Consumer1 - TIMEOUT Stage1 - trytake: " + i.ToString() + " elapsed " + DateTime.Now.Subtract(startTime).TotalSeconds.ToString() + Environment.NewLine);
                    }
                }
                if (tokenSource.IsCancellationRequested)
                {
                    message += "Consumer1 - Cancellation requested, exiting..." + Environment.NewLine;
                }
                else
                {
                    message += "Consumer1 - Emptied all items from Stage 1..." + Environment.NewLine;
                    stage2.CompleteAdding();
                }
            }, tokenSource.Token);

            //Reads prints data
            var task2 = Task.Factory.StartNew(() =>
            {
                int i = -1;
                while (!stage2.IsCompleted)
                {
                    if (tokenSource.IsCancellationRequested)
                    {
                        break;
                    }

                    if (stage2.TryTake(out i, 300))
                    {
                        message += ("T" + Thread.CurrentThread.ManagedThreadId.ToString()
                                    + " Consumer2 - Stage 2 Process: " + i.ToString() + " elapsed " + DateTime.Now.Subtract(startTime).TotalSeconds.ToString() + Environment.NewLine);
                        //Pause a little over half second to simulate work
                        Thread.Sleep(new TimeSpan(0, 0, 0, 0, 600));
                    }
                    else
                    {
                        message += ("T" + Thread.CurrentThread.ManagedThreadId.ToString()
                                    + " Consumer2 - TIMEOUT Stage2 [Try take]: exceeded at " + DateTime.Now.Subtract(startTime).TotalSeconds.ToString() + Environment.NewLine);
                    }
                }
            }, tokenSource.Token)
                        .ContinueWith((prevtask) =>
            {
                message += "WithoutBlocking Example - Completed." + Environment.NewLine;

                // Simple test for checking propagation of exceptions.
                // This works fine, simply check the task.WhenAll result, it will say faulted with a list of the exceptions thrown...easy
                //throw new System.NotImplementedException();
            }, tokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);

            Task.WhenAll(task0, task1, task2)
            .ContinueWith((prevTask) =>
            {
                CompletedEventArgs e = new CompletedEventArgs(prevTask);
                OnAllTasksCompleted(e);
            });
        }