Example #1
0
        static void Test()
        {
            ConcurrentExclusiveSchedulerPair pair = new ConcurrentExclusiveSchedulerPair();

            readerAB1 = new ActionBlock<int>((i) =>
            {
                Console.WriteLine(i + "  ReaderAB1 begin handing." + " Excute Time:" + DateTime.Now +
                                  " currentThreadId : " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
            }, new ExecutionDataflowBlockOptions() {TaskScheduler = pair.ConcurrentScheduler});

            readerAB2 = new ActionBlock<int>((i) =>
            {
                Console.WriteLine(i + "  ReaderAB2 begin handing." + " Excute Time:" + DateTime.Now +
                                  " currentThreadId : " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
            }, new ExecutionDataflowBlockOptions() {TaskScheduler = pair.ConcurrentScheduler});

            readerAB3 = new ActionBlock<int>((i) =>
            {
                Console.WriteLine(i + "  ReaderAB3 begin handing." + " Excute Time:" + DateTime.Now +
                                  " currentThreadId : " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(500);
            }, new ExecutionDataflowBlockOptions() {TaskScheduler = pair.ConcurrentScheduler});

            writeAB1 = new ActionBlock<int>((i) =>
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(i + "  writeAB1 begin handing." + " Excute Time:" + DateTime.Now +
                                  " currentThreadId : " + Thread.CurrentThread.ManagedThreadId);
                Console.ResetColor();
                Thread.Sleep(3000);
            }, new ExecutionDataflowBlockOptions() {TaskScheduler = pair.ExclusiveScheduler});

            bb.LinkTo(readerAB1);
            bb.LinkTo(readerAB2);
            bb.LinkTo(readerAB3);

            var task1 = Task.Run(() =>
            {
                while (true)
                {
                    bb.Post(1);
                    Thread.Sleep(1000);
                }
            });

            var task2 = Task.Run(() =>
            {
                while (true)
                {
                    writeAB1.Post(1);
                    Thread.Sleep(6000);
                }
            });

            Task.WaitAll(task1, task2);
        }
        public void BasicConcurrentUsageTest()
        {
            schedPair = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4);
            factory = new TaskFactory(schedPair.ConcurrentScheduler);

            bool launched = false;
            factory.StartNew(() => launched = true);
            Thread.Sleep(600);

            Assert.IsTrue(launched);
        }
Example #3
0
        public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
        {
            IRazorPageFactory pageFactory = new VirtualPathRazorPageFactory(context.InputFolder, context, _basePageType);
            List<IDocument> validInputs = inputs
                .Where(x => _ignorePrefix == null || !x.ContainsKey("SourceFileName") || !x.String("SourceFileName").StartsWith(_ignorePrefix))
                .ToList();

            // Compile the pages in parallel
            ConcurrentDictionary<IDocument, Tuple<ViewContext, ViewEngineResult>> compilationResults
                = new ConcurrentDictionary<IDocument, Tuple<ViewContext, ViewEngineResult>>();
            Parallel.ForEach(validInputs, x =>
            {
                context.Trace.Verbose("Compiling Razor for {0}", x.Source);
                IViewStartProvider viewStartProvider = new ViewStartProvider(pageFactory, _viewStartPath?.Invoke(x));
                IRazorViewFactory viewFactory = new RazorViewFactory(viewStartProvider);
                IRazorViewEngine viewEngine = new RazorViewEngine(pageFactory, viewFactory);
                ViewContext viewContext = new ViewContext(null, new ViewDataDictionary(), null, x.Metadata, context, viewEngine);
                ViewEngineResult viewEngineResult;
                using (Stream stream = x.GetStream())
                {
                    viewEngineResult = viewEngine.GetView(viewContext, GetRelativePath(x), stream).EnsureSuccessful();
                }
                compilationResults[x] = new Tuple<ViewContext, ViewEngineResult>(viewContext, viewEngineResult);
            });

            // Now evaluate them in sequence - have to do this because BufferedHtmlContent doesn't appear to work well in multi-threaded parallel execution
            TaskScheduler exclusiveScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler;
            CancellationToken cancellationToken = new CancellationToken();
            return validInputs
                .Select(x =>
                {
                    using (context.Trace.WithIndent().Verbose("Processing Razor for {0}", x.Source))
                    {
                        Tuple<ViewContext, ViewEngineResult> compilationResult;
                        if (compilationResults.TryGetValue(x, out compilationResult))
                        {
                            using (StringWriter writer = new StringWriter())
                            {
                                compilationResult.Item1.View = compilationResult.Item2.View;
                                compilationResult.Item1.Writer = writer;
                                Task.Factory.StartNew(() => compilationResult.Item2.View.RenderAsync(compilationResult.Item1),
                                    cancellationToken, TaskCreationOptions.None, exclusiveScheduler).Unwrap().GetAwaiter().GetResult();
                                return x.Clone(writer.ToString());
                            }
                        }
                        context.Trace.Warning("Could not find compilation result for {0}", x.Source);
                        return null;
                    }
                });
        }
		public void ExclusiveUsageTest ()
		{
			schedPair = new ConcurrentExclusiveSchedulerPair (TaskScheduler.Default, 4);
			factory = new TaskFactory (schedPair.ExclusiveScheduler);

			int count = 0;
			ManualResetEventSlim mreFinish = new ManualResetEventSlim (false);
			ManualResetEventSlim mreStart = new ManualResetEventSlim (false);

			factory.StartNew (() => {
					mreStart.Set ();
					Interlocked.Increment (ref count);
					mreFinish.Wait ();
				});
			mreStart.Wait ();
			factory.StartNew (() => Interlocked.Increment (ref count));
			Thread.Sleep (100);

			Assert.AreEqual (1, count);
			mreFinish.Set ();
		}
Example #5
0
        private static async Task Main(string[] args)
        {
            var          inputBlock          = new BroadcastBlock <int>(a => a);
            var          taskScheduler       = new System.Threading.Tasks.ConcurrentExclusiveSchedulerPair();
            Action <int> actionBlockFunction = (int a) =>
            {
                var counterValue = GetSharedObjectValue();
                //very complexLogic
                Task.Delay(_random.Next(300)).Wait();
                Console.WriteLine($"The counter value I've read was {counterValue} " +
                                  $"Now it is {_sharedCounter} " +
                                  $"I will set it to {counterValue + 1}");
                SetSharedObjectValue(counterValue + 1);
            };
            var incrementingBlock1 = new ActionBlock <int>(actionBlockFunction
                                                           , new ExecutionDataflowBlockOptions()
            {
                TaskScheduler = taskScheduler.ExclusiveScheduler
            });
            var incrementingBlock2 = new ActionBlock <int>(actionBlockFunction
                                                           , new ExecutionDataflowBlockOptions()
            {
                TaskScheduler = taskScheduler.ExclusiveScheduler
            });

            inputBlock.LinkToWithPropagation(incrementingBlock1);
            inputBlock.LinkToWithPropagation(incrementingBlock2);

            for (int i = 0; i < 10; i++)
            {
                inputBlock.Post(i);
            }

            inputBlock.Complete();
            await incrementingBlock1.Completion;
            await incrementingBlock2.Completion;

            Console.WriteLine($"Current counter value {GetSharedObjectValue()}");
        }
        public void Run()
        {
            var propagateCompletion = new DataflowLinkOptions { PropagateCompletion = true };

            var csep = new ConcurrentExclusiveSchedulerPair();
            var concurrentOptions = new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = 2,
                TaskScheduler = csep.ConcurrentScheduler
            };

            var exclusiveOptions = new ExecutionDataflowBlockOptions
            {
                TaskScheduler = csep.ExclusiveScheduler
            };

            var concurrent = new ActionBlock<int>(async i =>
            {
                Console.WriteLine("Concurent print value: {0}", i);
                await Task.Delay(500);
            }, concurrentOptions);

            var exclusive = new ActionBlock<int>(i =>
            {
                Console.WriteLine("Exclusive print value: {0}", i);
                Thread.Sleep(750);
            }, exclusiveOptions);

            var broadcaster = new BroadcastBlock<int>(i => i);
            broadcaster.LinkTo(concurrent, propagateCompletion);
            broadcaster.LinkTo(exclusive, propagateCompletion, i => i % 2 == 0);

            Enumerable
              .Range(1, 10)
              .ToList()
              .ForEach(i => broadcaster.Post(i));
            broadcaster.Complete();
            Task.WaitAll(concurrent.Completion, exclusive.Completion);
        }
        public static void TestConcurrentBlockage(bool useReader)
        {
            ConcurrentExclusiveSchedulerPair schedPair = new ConcurrentExclusiveSchedulerPair();
            TaskFactory readers = new TaskFactory(schedPair.ConcurrentScheduler);
            TaskFactory writers = new TaskFactory(schedPair.ExclusiveScheduler);
            ManualResetEvent blockExclusiveTaskEvent = new ManualResetEvent(false);
            ManualResetEvent blockMainThreadEvent = new ManualResetEvent(false);
            ManualResetEvent blockMre = new ManualResetEvent(false);

            //Schedule a concurrent task and ensure that it is executed, just for fun
            Task<bool> conTask = readers.StartNew<bool>(() => { new ManualResetEvent(false).WaitOne(10); ; return true; });
            conTask.Wait();
            Assert.True(conTask.Result, "The concurrenttask when executed successfully should have returned true");

            //Now scehdule a exclusive task that is blocked(thereby preventing other concurrent tasks to finish)
            Task<bool> exclusiveTask = writers.StartNew<bool>(() => { blockMainThreadEvent.Set(); blockExclusiveTaskEvent.WaitOne(); return true; });

            //With exclusive task in execution mode, schedule a number of concurrent tasks and ensure they are not executed
            blockMainThreadEvent.WaitOne();
            List<Task> taskList = new List<Task>();
            for (int i = 0; i < 20; i++) taskList.Add(readers.StartNew<bool>(() => { blockMre.WaitOne(10); return true; }));

            foreach (Task task in taskList)
            {
                bool wasTaskStarted = (task.Status != TaskStatus.Running) && (task.Status != TaskStatus.RanToCompletion);
                Assert.True(wasTaskStarted, "Concurrent tasks should not be executed when a exclusive task is getting executed");
            }

            blockExclusiveTaskEvent.Set();
            Task.WaitAll(taskList.ToArray());
        }
        public static void TestIntegration(String apiType, bool useReader)
        {
            Debug.WriteLine(string.Format(" Running apiType:{0} useReader:{1}", apiType, useReader));
            int taskCount = Environment.ProcessorCount; //To get varying number of tasks as a function of cores
            ConcurrentExclusiveSchedulerPair schedPair = new ConcurrentExclusiveSchedulerPair();
            CountdownEvent cde = new CountdownEvent(taskCount); //Used to track how many tasks were executed
            Action work = () => { cde.Signal(); }; //Work done by all APIs
            //Choose the right scheduler to use based on input parameter
            TaskScheduler scheduler = useReader ? schedPair.ConcurrentScheduler : schedPair.ExclusiveScheduler;

            SelectAPI2Target(apiType, taskCount, scheduler, work);
            cde.Wait(); //This will cause the test to block (and timeout) until all tasks are finished
        }
        public static void TestMaxItemsPerTask(int maxConcurrency, int maxItemsPerTask, bool completeBeforeTaskWait)
        {
            //Create a custom TaskScheduler with specified max concurrency (TrackingTaskScheduler is defined in Common\tools\CommonUtils\TPLTestSchedulers.cs)
            TrackingTaskScheduler scheduler = new TrackingTaskScheduler(maxConcurrency);
            //We need to use the custom scheduler to achieve the results. As a by-product, we test to ensure custom schedulers are supported
            ConcurrentExclusiveSchedulerPair schedPair = new ConcurrentExclusiveSchedulerPair(scheduler, maxConcurrency, maxItemsPerTask);
            TaskFactory readers = new TaskFactory(schedPair.ConcurrentScheduler); //get reader and writer schedulers
            TaskFactory writers = new TaskFactory(schedPair.ExclusiveScheduler);

            //These are threadlocals to ensure that no concurrency side effects occur
            ThreadLocal<int> itemsExecutedCount = new ThreadLocal<int>(); //Track the items executed by CEScheduler Task
            ThreadLocal<int> schedulerIDInsideTask = new ThreadLocal<int>(); //Used to store the Scheduler ID observed by a Task Executed by CEScheduler Task

            //Work done by both reader and writer tasks  
            Action work = () =>
            {
                //Get the id of the parent Task (which is the task created by the scheduler). Each task run by the scheduler task should
                //see the same SchedulerID value since they are run on the same thread
                int id = ((TrackingTaskScheduler)scheduler).SchedulerID.Value;
                if (id == schedulerIDInsideTask.Value)
                { //since ids match, this is one more Task being executed by the CEScheduler Task
                    itemsExecutedCount.Value = ++itemsExecutedCount.Value;
                    //This does not need to be thread safe since we are looking to ensure that only n number of tasks were executed and not the order
                    //in which they were executed. Also asserting inside the thread is fine since we just want the test to be marked as failure
                    Assert.True(itemsExecutedCount.Value <= maxItemsPerTask, string.Format("itemsExecutedCount={0} cant be greater than maxValue={1}. Parent TaskID={2}",
                        itemsExecutedCount, maxItemsPerTask, id));
                }
                else
                { //Since ids dont match, this is the first Task being executed in the CEScheduler Task
                    schedulerIDInsideTask.Value = id; //cache the scheduler ID seen by the thread, so other tasks running in same thread can see this
                    itemsExecutedCount.Value = 1;
                }
                //Give enough time for a Task to stay around, so that other tasks will be executed by the same CEScheduler Task
                //or else the CESchedulerTask will die and each Task might get executed by a different CEScheduler Task. This does not affect the 
                //verifications, but its increases the chance of finding a bug if the maxItemPerTask is not respected
                new ManualResetEvent(false).WaitOne(20);
            };

            List<Task> taskList = new List<Task>();
            int maxConcurrentTasks = maxConcurrency * maxItemsPerTask * 5;
            int maxExclusiveTasks = maxConcurrency * maxItemsPerTask * 2;

            // Schedule Tasks in both concurrent and exclusive mode
            for (int i = 0; i < maxConcurrentTasks; i++)
                taskList.Add(readers.StartNew(work));
            for (int i = 0; i < maxExclusiveTasks; i++)
                taskList.Add(writers.StartNew(work));

            if (completeBeforeTaskWait)
            {
                schedPair.Complete();
                schedPair.Completion.Wait();
                Assert.True(taskList.TrueForAll(t => t.IsCompleted), "All tasks should have completed for scheduler to complete");
            }

            //finally wait for all of the tasks, to ensure they all executed properly
            Task.WaitAll(taskList.ToArray());

            if (!completeBeforeTaskWait)
            {
                schedPair.Complete();
                schedPair.Completion.Wait();
                Assert.True(taskList.TrueForAll(t => t.IsCompleted), "All tasks should have completed for scheduler to complete");
            }
        }
Example #10
0
        public static void TestLowerConcurrencyLevel()
        {
            //a custom scheduler with maxConcurrencyLevel of one
            int customSchedulerConcurrency = 1;
            TrackingTaskScheduler scheduler = new TrackingTaskScheduler(customSchedulerConcurrency);
            // specify a maxConcurrencyLevel > TaskScheduler's maxconcurrencyLevel to ensure the pair takes the min of the two
            ConcurrentExclusiveSchedulerPair schedPair = new ConcurrentExclusiveSchedulerPair(scheduler, Int32.MaxValue);
            Assert.Equal(scheduler.MaximumConcurrencyLevel, schedPair.ConcurrentScheduler.MaximumConcurrencyLevel);

            //Now schedule a reader task that would block and verify that more reader tasks scheduled are not executed 
            //(as long as the first task is blocked)
            TaskFactory readers = new TaskFactory(schedPair.ConcurrentScheduler);
            ManualResetEvent blockReaderTaskEvent = new ManualResetEvent(false);
            ManualResetEvent blockMainThreadEvent = new ManualResetEvent(false);

            //Add a reader tasks that would block
            readers.StartNew(() => { blockMainThreadEvent.Set(); blockReaderTaskEvent.WaitOne(); });
            blockMainThreadEvent.WaitOne(); // wait for the blockedTask to start execution

            //Now add more reader tasks
            int maxConcurrentTasks = Environment.ProcessorCount;
            List<Task> taskList = new List<Task>();
            for (int i = 0; i < maxConcurrentTasks; i++)
                taskList.Add(readers.StartNew(() => { })); //schedule some dummy reader tasks

            foreach (Task task in taskList)
            {
                bool wasTaskStarted = (task.Status != TaskStatus.Running) && (task.Status != TaskStatus.RanToCompletion);
                Assert.True(wasTaskStarted, string.Format("Additional reader tasks should not start when scheduler concurrency is {0} and a reader task is blocked", customSchedulerConcurrency));
            }

            //finally unblock the blocjedTask and wait for all of the tasks, to ensure they all executed properly
            blockReaderTaskEvent.Set();
            Task.WaitAll(taskList.ToArray());
        }
        public void ExclusiveUsageWithConcurrentExecutingTest()
        {
            schedPair = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4);
            TaskFactory exclFact = new TaskFactory(schedPair.ExclusiveScheduler);
            TaskFactory concFact = new TaskFactory(schedPair.ConcurrentScheduler);

            int count = 0;
            bool started = false;
            ManualResetEventSlim mreStart = new ManualResetEventSlim(false);
            ManualResetEventSlim mreFinish = new ManualResetEventSlim(false);

            concFact.StartNew(() =>
            {
                started = true;
                mreStart.Set();
                mreFinish.Wait();
                started = false;
            });

            mreStart.Wait();

            exclFact.StartNew(() => Interlocked.Increment(ref count));
            Thread.Sleep(100);

            Assert.IsTrue(started);
            Assert.AreEqual(0, count);
            mreFinish.Set();
        }
 /// <summary>Initializes the debug view.</summary>
 /// <param name="pair">The pair being debugged.</param>
 public DebugView(ConcurrentExclusiveSchedulerPair pair)
 {
     Debug.Assert(pair != null, "Need a pair with which to construct the debug view.");
     m_pair = pair;
 }
        public void ConcurrentUsageTest()
        {
            schedPair = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 4);
            factory = new TaskFactory(schedPair.ConcurrentScheduler);

            int count = 0;
            ManualResetEventSlim mreFinish = new ManualResetEventSlim(false);
            CountdownEvent cntd = new CountdownEvent(2);

            factory.StartNew(() =>
            {
                Interlocked.Increment(ref count);
                cntd.Signal();
                mreFinish.Wait();
            });
            factory.StartNew(() =>
            {
                Interlocked.Increment(ref count);
                cntd.Signal();
                mreFinish.Wait();
            });

            cntd.Wait();
            Assert.AreEqual(2, count);
            mreFinish.Set();
        }
Example #14
0
        public static void TestConcurrentExclusiveChain(bool syncContinuations)
        {
            var scheduler = new TrackingTaskScheduler(Environment.ProcessorCount);
            var cesp = new ConcurrentExclusiveSchedulerPair(scheduler);

            // continuations
            {
                var starter = new Task(() => { });
                var t = starter;
                for (int i = 0; i < 10; i++)
                {
                    t = t.ContinueWith(delegate { }, CancellationToken.None, syncContinuations ? TaskContinuationOptions.ExecuteSynchronously : TaskContinuationOptions.None, cesp.ConcurrentScheduler);
                    t = t.ContinueWith(delegate { }, CancellationToken.None, syncContinuations ? TaskContinuationOptions.ExecuteSynchronously : TaskContinuationOptions.None, cesp.ExclusiveScheduler);
                }
                starter.Start(cesp.ExclusiveScheduler);
                t.Wait();
            }

            // parent/child
            {
                var errorString = "hello faulty world";
                var root = Task.Factory.StartNew(() =>
                {
                    Task.Factory.StartNew(() =>
                    {
                        Task.Factory.StartNew(() =>
                        {
                            Task.Factory.StartNew(() =>
                            {
                                Task.Factory.StartNew(() =>
                                {
                                    Task.Factory.StartNew(() =>
                                    {
                                        Task.Factory.StartNew(() =>
                                        {
                                            throw new InvalidOperationException(errorString);
                                        }, CancellationToken.None, TaskCreationOptions.AttachedToParent, cesp.ExclusiveScheduler).Wait();
                                    }, CancellationToken.None, TaskCreationOptions.AttachedToParent, cesp.ExclusiveScheduler);
                                }, CancellationToken.None, TaskCreationOptions.AttachedToParent, cesp.ConcurrentScheduler);
                            }, CancellationToken.None, TaskCreationOptions.AttachedToParent, cesp.ExclusiveScheduler);
                        }, CancellationToken.None, TaskCreationOptions.AttachedToParent, cesp.ConcurrentScheduler);
                    }, CancellationToken.None, TaskCreationOptions.AttachedToParent, cesp.ExclusiveScheduler);
                }, CancellationToken.None, TaskCreationOptions.None, cesp.ConcurrentScheduler);

                ((IAsyncResult)root).AsyncWaitHandle.WaitOne();
                Assert.True(root.IsFaulted, "Root should have been faulted by child's error");
                var ae = root.Exception.Flatten();
                Assert.True(ae.InnerException is InvalidOperationException && ae.InnerException.Message == errorString,
                    "Child's exception should have propagated to the root.");
            }
        }
 public void Synchronous_client_call_from_async_context_using_exclusive_scheduler_is_not_deadlocked()
 {
     // Note that this will probably leave a hanging worker thread if failing :/
     // Not sure how to clean that up properly, might have to implement a custom TaskScheduler to do that
     var ccsp = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 1);
     var tf = new TaskFactory(CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskContinuationOptions.None,
                              ccsp.ExclusiveScheduler);
     // Should have good time to complete in 10seconds, on any computer
     var hasCompleted = tf.StartNew(async () =>
     {
         // Just do some random sync client call
         Client.Critters.Post(new CritterForm() { Name = "hi" });
         await Task.Yield();
         Client.Critters.Post(new CritterForm() { Name = "again" });
     }).Wait(10000);
     Assert.That(hasCompleted, Is.True, "Task never completed, which means it's probably deadlocked.");
 }
		/// <summary>
		/// Initializes a new instance of the <see cref="AsyncReaderWriterLock"/> class.
		/// </summary>
		public AsyncReaderWriterLock()
		{
			// Built upon ConcurrentExclusiveSchedulerPair is a .Net TPL construct that provides exactly what we need
			// - reader/writer orchestration
			ConcurrentExclusiveSchedulerPair = new ConcurrentExclusiveSchedulerPair();

			ConcurrentNonExclusiveTaskFactory = new TaskFactory(this.ConcurrentExclusiveSchedulerPair.ConcurrentScheduler);
			ExclusiveTaskFactory = new TaskFactory(this.ConcurrentExclusiveSchedulerPair.ExclusiveScheduler);
		}
 public InnerTaskScheduler(ConcurrentExclusiveSchedulerPair scheduler,
                           ConcurrentQueue <Task> queue)
 {
     this.scheduler = scheduler;
     this.queue     = queue;
 }
        public void RunConcurrentExclusiveSchedulerPairRWTests()
        {
            // Validate reader tasks get scheduled concurrently
            {
                bool localPassed = true;
                foreach (var cesp in new[] { new ConcurrentExclusiveSchedulerPair(), new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, -1) })
                {
                    try
                    {
                        int numToSchedule = Environment.ProcessorCount; // doesn't validate much on a single core, but that's ok
                        Barrier b = new Barrier(numToSchedule);
                        var tasks = new Task[numToSchedule];
                        for (int i = 0; i < numToSchedule; i++)
                        {
                            tasks[i] = Task.Factory.StartNew(() =>
                            {
                                localPassed &= b.SignalAndWait(1000);
                            }, CancellationToken.None, TaskCreationOptions.None, cesp.ConcurrentScheduler);
                        }
                        Task.WaitAll(tasks);
                    }
                    finally { cesp.Complete(); }
                }

                Assert.True(localPassed, string.Format("{0}: Test concurrent readers", localPassed ? "Success" : "Failure"));
            }

            // Validate reader tasks don't go above max concurrency level
            {
                bool localPassed = true;
                int mcl = 2;
                var cesp = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, mcl);
                try
                {
                    int numToSchedule = 2;
                    int concurrentTasks = 0;
                    var tasks = new Task[numToSchedule];
                    for (int i = 0; i < numToSchedule; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() =>
                        {
                            Interlocked.Increment(ref concurrentTasks);
                            Task.Delay(1).Wait();
                            if (concurrentTasks > mcl) localPassed = false;
                            Task.Delay(1).Wait();
                            Interlocked.Decrement(ref concurrentTasks);
                        }, CancellationToken.None, TaskCreationOptions.None, cesp.ConcurrentScheduler);
                    }
                    Task.WaitAll(tasks);
                }
                finally { cesp.Complete(); }
                Assert.True(localPassed, string.Format("{0}: Test concurrent readers stay below maximum", localPassed ? "Success" : "Failure"));
            }

            // Validate writers tasks don't run concurrently with each other
            {
                bool localPassed = true;
                var cesp = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default);
                try
                {
                    int numToSchedule = 2;
                    int concurrentTasks = 0;
                    var tasks = new Task[numToSchedule];
                    for (int i = 0; i < numToSchedule; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() =>
                        {
                            Interlocked.Increment(ref concurrentTasks);
                            Task.Delay(100).Wait();
                            if (concurrentTasks > 1) localPassed &= false;
                            Task.Delay(100).Wait();
                            Interlocked.Decrement(ref concurrentTasks);
                        }, CancellationToken.None, TaskCreationOptions.None, cesp.ExclusiveScheduler);
                    }
                    Task.WaitAll(tasks);
                }
                finally { cesp.Complete(); }
                Assert.True(localPassed, string.Format("{0}: Test writers don't run concurrently with each other", localPassed ? "Success" : "Failure"));
            }

            // Validate writers tasks don't run concurrently with readers or writers
            {
                bool localPassed = true;
                var cesp = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default);

                int numWritersToSchedule = 2;
                int numReadersToSchedule = 3;
                int runningTasks = 0;

                var readerTasks = new Task[numReadersToSchedule];
                for (int i = 0; i < numReadersToSchedule; i++)
                {
                    readerTasks[i] = Task.Factory.StartNew(() =>
                    {
                        Interlocked.Increment(ref runningTasks);
                        Task.Delay(1).Wait();
                        Interlocked.Decrement(ref runningTasks);
                    }, CancellationToken.None, TaskCreationOptions.None, cesp.ConcurrentScheduler);
                }

                var writerTasks = new Task[numWritersToSchedule];
                for (int i = 0; i < numWritersToSchedule; i++)
                {
                    writerTasks[i] = Task.Factory.StartNew(() =>
                    {
                        Interlocked.Increment(ref runningTasks);
                        Task.Delay(100).Wait();
                        if (runningTasks > 1) localPassed &= false;
                        Task.Delay(100).Wait();
                        Interlocked.Decrement(ref runningTasks);
                    }, CancellationToken.None, TaskCreationOptions.None, cesp.ExclusiveScheduler);
                }

                Task.WaitAll(writerTasks);
                Task.WaitAll(readerTasks);

                // not completing the cesp here, just so that some of our tests don't
                // and so that we don't hide any issues by always completing

                Assert.True(localPassed, string.Format("{0}: Test writers don't run concurrently with anything", localPassed ? "Success" : "Failure"));
            }
        }
        public void RunConcurrentExclusiveSchedulerPairTests()
        {
            // Validate invalid arguments
            {
                Assert.Throws<ArgumentNullException>(() => new ConcurrentExclusiveSchedulerPair(null));
                Assert.Throws<ArgumentOutOfRangeException>(() => new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, -2));
                Assert.Throws<ArgumentOutOfRangeException>(() => new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 0));
                Assert.Throws<ArgumentOutOfRangeException>(() => new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 1, -2));
                Assert.Throws<ArgumentOutOfRangeException>(() => new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, 1, 0));
            }

            // Validate completion prevents more tasks
            {
                bool localPassed = true;
                ConcurrentExclusiveSchedulerPair cesp = new ConcurrentExclusiveSchedulerPair();
                cesp.Complete();
                Assert.Throws<TaskSchedulerException>(() => Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, cesp.ConcurrentScheduler).Wait());
                Assert.Throws<TaskSchedulerException>(() => Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, cesp.ExclusiveScheduler).Wait());
                Assert.True(localPassed, string.Format("{0}: Completion prevents more tasks", localPassed ? "Success" : "Failure"));
            }

            // Validate completion allows existing scheduled tasks to complete
            {
                bool localPassed = true;
                ConcurrentExclusiveSchedulerPair cesp = new ConcurrentExclusiveSchedulerPair();
                int tasksToSchedule = 2;
                int count = 0;
                var tasks = new Task[tasksToSchedule];
                using (var mres = new ManualResetEventSlim())
                {
                    for (int i = 0; i < tasksToSchedule; i++)
                    {
                        tasks[i] = Task.Factory.StartNew(() =>
                        {
                            mres.Wait();
                            Interlocked.Increment(ref count);
                        }, CancellationToken.None, TaskCreationOptions.None, cesp.ExclusiveScheduler);
                    }
                    cesp.Complete();
                    Assert.True(count == 0, "No tasks should have completed yet");
                    mres.Set();
                    Task.WaitAll(tasks);
                    Assert.True(count == tasksToSchedule, "All of the tasks should have executed");
                    cesp.Completion.Wait();
                }
                Assert.True(localPassed, string.Format("{0}: Completion allows existing tasks to complete", localPassed ? "Success" : "Failure"));
            }

            //  Validate MCL handling
            {
                bool localPassed = true;
                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(new ControllableMclTaskScheduler(4), 8);
                    localPassed &= cesp.ConcurrentScheduler.MaximumConcurrencyLevel == 4;
                    localPassed &= cesp.ExclusiveScheduler.MaximumConcurrencyLevel == 1;
                }

                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(new ControllableMclTaskScheduler(8), 4);
                    localPassed &= cesp.ConcurrentScheduler.MaximumConcurrencyLevel == 4;
                    localPassed &= cesp.ExclusiveScheduler.MaximumConcurrencyLevel == 1;
                }

                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, -1);
                    localPassed &= cesp.ConcurrentScheduler.MaximumConcurrencyLevel == Int32.MaxValue;
                    localPassed &= cesp.ExclusiveScheduler.MaximumConcurrencyLevel == 1;
                }

                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(new ControllableMclTaskScheduler(-2), -1);
                    localPassed &= cesp.ConcurrentScheduler.MaximumConcurrencyLevel == Int32.MaxValue;
                    localPassed &= cesp.ExclusiveScheduler.MaximumConcurrencyLevel == 1;
                }

                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(new ControllableMclTaskScheduler(-2), 1);
                    localPassed &= cesp.ConcurrentScheduler.MaximumConcurrencyLevel == 1;
                    localPassed &= cesp.ExclusiveScheduler.MaximumConcurrencyLevel == 1;
                }

                Assert.True(localPassed, string.Format("{0}: Max Concurrency Level corner cases handling correctly", localPassed ? "Success" : "Failure"));
            }

            // Validate queueing when layering on a faulty scheduler
            {
                bool localPassed = true;
                var ts = new ControllableTaskScheduler();

                // NOTE: We're using new pair instances on each iteration to avoid code paths
                // where a replica task gets queued up in the scheduler.  If that happens while the underlying
                // scheduler is FailQueueing==true, the task used internally by CESP will fault
                // and will go unobserved.  This is by design and we don't want it bringing down the tests.
                var cesp1 = new ConcurrentExclusiveSchedulerPair(ts);
                var cesp2 = new ConcurrentExclusiveSchedulerPair(ts);
                foreach (var cesp in new[] { cesp1, cesp2 })
                {
                    var scheduler = cesp == cesp1 ? cesp1.ConcurrentScheduler : cesp2.ExclusiveScheduler;

                    // Queue a task that will cause the CESP to fail queueing to its underlying scheduler
                    ts.FailQueueing = true;
                    Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, scheduler);

                    try
                    {
                        Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, scheduler);
                        localPassed = false;
                    }
                    catch (Exception exc)
                    {
                        Assert.True(
                            exc is TaskSchedulerException && ((TaskSchedulerException)exc).InnerException is InvalidOperationException,
                            "Expected a TaskSchedulerException containing an InvalidOperationException");
                    }

                    Assert.True(SpinWait.SpinUntil(() => cesp.Completion.IsCompleted, 1), "Excepted CESP to complete in allotted time");
                    Assert.True(cesp.Completion.Exception != null, "Excepted CESP task to have exceptions");
                }

                Assert.True(localPassed, string.Format("{0}: Test queueing layering on faulty scheduler", localPassed ? "Success" : "Failure"));
            }

            // Validate inlining when layering on a faulty scheduler
            {
                bool localPassed = true;
                var ts = new ControllableTaskScheduler();

                // NOTE: We're using new pair instances on each iteration to avoid code paths
                // where a replica task gets queued up in the scheduler.  If that happens while the underlying
                // scheduler is FailQueueing==true, the task used internally by CESP will fault
                // and will go unobserved.  This is by design and we don't want it bringing down the tests.
                var cesp1 = new ConcurrentExclusiveSchedulerPair(ts);
                var cesp2 = new ConcurrentExclusiveSchedulerPair(ts);
                foreach (var cesp in new[] { cesp1, cesp2 })
                {
                    var scheduler = cesp == cesp1 ? cesp1.ConcurrentScheduler : cesp2.ExclusiveScheduler;

                    // Inline a task that will cause the CESP to fail queueing to its underlying scheduler
                    ts.FailQueueing = false;
                    Task.Factory.StartNew(() =>
                    {
                        ts.FailQueueing = true;
                        Task t = new Task(() => { });
                        try
                        {
                            t.RunSynchronously(scheduler);
                            localPassed = false;
                        }
                        catch (Exception exc)
                        {
                            Assert.True(
                                exc is TaskSchedulerException && ((TaskSchedulerException)exc).InnerException is TaskSchedulerException,
                                "Excepted a TaskSchedulerException to contain another TaskSchedulerException");
                        }
                        Assert.True(t.IsCompleted, "Expected the queued task to be completed");
                        Assert.True(t.Exception != null, "Expected the queued task to be faulted");
                    }, CancellationToken.None, TaskCreationOptions.None, scheduler).Wait();

                    ts.FailQueueing = false;
                    Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, scheduler).Wait();
                    cesp.Complete();

                    Assert.True(SpinWait.SpinUntil(() => cesp.Completion.IsCompleted, 1), "Expected the CESP to complete in the allotted time");
                    Assert.True(cesp.Completion.Exception == null, "Expected the task to not be faulted and have no exceptions");
                }

                Assert.True(localPassed, string.Format("{0}: Test inlining layering on faulty scheduler", localPassed ? "Success" : "Failure"));
            }

            // Validate tasks on the same scheduler waiting on each other
            {
                bool localPassed = true;
                foreach (var underlyingScheduler in new[] { TaskScheduler.Default, new ControllableTaskScheduler() { FailQueueing = false } })
                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(underlyingScheduler);
                    TaskRecursion(2, new ParallelOptions { TaskScheduler = cesp.ExclusiveScheduler });
                    cesp.Complete();

                    cesp = new ConcurrentExclusiveSchedulerPair(underlyingScheduler);
                    TaskRecursion(2, new ParallelOptions { TaskScheduler = cesp.ConcurrentScheduler });
                    cesp.Complete();
                }
                Assert.True(localPassed, string.Format("{0}: Recursively waiting on same scheduler", localPassed ? "Success" : "Failure"));
            }

            // Exercise additional inlining code paths
            {
                bool localPassed = true;
                foreach (var underlyingScheduler in new[] { TaskScheduler.Default, new ControllableTaskScheduler() { FailQueueing = false } })
                {
                    var cesp = new ConcurrentExclusiveSchedulerPair(underlyingScheduler);
                    Task.Factory.StartNew(() => { }).ContinueWith(_ => { }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, cesp.ExclusiveScheduler).Wait();
                    Task.Factory.StartNew(() => { }).ContinueWith(_ => { }, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, cesp.ConcurrentScheduler).Wait();

                    var t = new Task(() => { });
                    t.RunSynchronously(cesp.ConcurrentScheduler);
                    t.Wait();

                    t = new Task(() => { });
                    t.RunSynchronously(cesp.ExclusiveScheduler);
                    t.Wait();

                    Task.Factory.StartNew(() =>
                    {
                        new Task(() => { }, TaskCreationOptions.AttachedToParent).RunSynchronously(cesp.ConcurrentScheduler);
                    }, CancellationToken.None, TaskCreationOptions.None, cesp.ConcurrentScheduler).Wait();

                    Task.Factory.StartNew(() =>
                    {
                        new Task(() => { }, TaskCreationOptions.AttachedToParent).RunSynchronously(cesp.ExclusiveScheduler);
                    }, CancellationToken.None, TaskCreationOptions.None, cesp.ExclusiveScheduler).Wait();
                }
                Assert.True(localPassed, string.Format("{0}: Additional inlining code paths", localPassed ? "Success" : "Failure"));
            }
        }
Example #20
0
        public static void TestCompletionTask()
        {
            // Completion tasks is valid after initialization
            {
                var cesp = new ConcurrentExclusiveSchedulerPair();
                Assert.True(cesp.Completion != null, "CompletionTask should never be null (after initialization)");
                Assert.True(!cesp.Completion.IsCompleted, "CompletionTask should not have completed");
            }

            // Completion task is valid after complete is called
            {
                var cesp = new ConcurrentExclusiveSchedulerPair();
                cesp.Complete();
                Assert.True(cesp.Completion != null, "CompletionTask should never be null (after complete)");
                cesp.Completion.Wait();
            }

            // Complete method may be called multiple times, and CompletionTask still completes
            {
                var cesp = new ConcurrentExclusiveSchedulerPair();
                for (int i = 0; i < 20; i++) cesp.Complete(); // ensure multiple calls to Complete succeed
                Assert.True(cesp.Completion != null, "CompletionTask should never be null (after multiple completes)");
                cesp.Completion.Wait();
            }

            // Can create a bunch of schedulers, do work on them all, complete them all, and they all complete
            {
                var cesps = new ConcurrentExclusiveSchedulerPair[100];
                for (int i = 0; i < cesps.Length; i++)
                {
                    cesps[i] = new ConcurrentExclusiveSchedulerPair();
                }
                for (int i = 0; i < cesps.Length; i++)
                {
                    Action work = () => new ManualResetEvent(false).WaitOne(2); ;
                    Task.Factory.StartNew(work, CancellationToken.None, TaskCreationOptions.None, cesps[i].ConcurrentScheduler);
                    Task.Factory.StartNew(work, CancellationToken.None, TaskCreationOptions.None, cesps[i].ExclusiveScheduler);
                }
                for (int i = 0; i < cesps.Length; i++)
                {
                    cesps[i].Complete();
                    cesps[i].Completion.Wait();
                }
            }

            // Validate that CESP does not implement IDisposable
            Assert.Equal(null, new ConcurrentExclusiveSchedulerPair() as IDisposable);
        }
		public void ReaderWriterLockUsage()
		{
			// для секций с известной операцией доступа (чтение или запись) можно использовать
			// ReaderWriterLockSlim (ReaderWriterLock не рекомендуется)
			ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();

			rwLock.EnterReadLock();
			// критическая секция с чтением данных
			rwLock.ExitReadLock();

			rwLock.EnterWriteLock();
			// критическая секция с изменением данных
			rwLock.ExitWriteLock();

			// также существует класс ConcurrentExclusiveSchedulerPair,
			// который содержит 2 менеджера заданий
			// все задания в ExclusiveScheduler выполняются по одному, 
			// если не выполняется ни одно задание в ConcurrentScheduler
			// все задания в ConcurrentScheduler выполняются одновременно, 
			// если не выполняется ни одно задание в ExclusiveScheduler
			ConcurrentExclusiveSchedulerPair schedulerPair = new ConcurrentExclusiveSchedulerPair();
			TaskFactory exclusiveFactory = new TaskFactory(schedulerPair.ExclusiveScheduler);
			exclusiveFactory.StartNew(() => Console.WriteLine(DateTime.Now.ToLongTimeString()));

			// класс, который блокирует поток, пока внутренний счётчик не достигнет нуля
			CountdownEvent countdownEvent = new CountdownEvent(5);
			countdownEvent.Wait();
			// критическая секция
			countdownEvent.Signal(2); // блокировка не снята
			countdownEvent.Signal(3); // блокировка снята

			// класс Barrier предоставляет возможность совокупности потоков проходить
			// через определённые шаги исполнения одновременно
		}
Example #22
0
        public static void TestSchedulerNesting()
        {
            // Create a hierarchical set of scheduler pairs
            var cespParent = new ConcurrentExclusiveSchedulerPair();

            var cespChild1 = new ConcurrentExclusiveSchedulerPair(cespParent.ConcurrentScheduler);
            var cespChild1Child1 = new ConcurrentExclusiveSchedulerPair(cespChild1.ConcurrentScheduler);
            var cespChild1Child2 = new ConcurrentExclusiveSchedulerPair(cespChild1.ExclusiveScheduler);

            var cespChild2 = new ConcurrentExclusiveSchedulerPair(cespParent.ExclusiveScheduler);
            var cespChild2Child1 = new ConcurrentExclusiveSchedulerPair(cespChild2.ConcurrentScheduler);
            var cespChild2Child2 = new ConcurrentExclusiveSchedulerPair(cespChild2.ExclusiveScheduler);

            // these are ordered such that we will complete the child schedulers before we complete their parents.  That way
            // we don't complete a parent that's still in use.
            var cesps = new[] {
                cespChild1Child1,
                cespChild1Child2,
                cespChild1,
                cespChild2Child1,
                cespChild2Child2,
                cespChild2,
                cespParent,
            };

            // Get the schedulers from all of the pairs
            List<TaskScheduler> schedulers = new List<TaskScheduler>();
            foreach (var s in cesps)
            {
                schedulers.Add(s.ConcurrentScheduler);
                schedulers.Add(s.ExclusiveScheduler);
            }

            // Keep track of all created tasks
            var tasks = new List<Task>();

            // Queue lots of work to each scheduler
            foreach (var scheduler in schedulers)
            {
                // Create a function that schedules and inlines recursively queued tasks
                Action<int> recursiveWork = null;
                recursiveWork = depth =>
                {
                    if (depth > 0)
                    {
                        Action work = () =>
                        {
                            new ManualResetEvent(false).WaitOne(1);
                            recursiveWork(depth - 1);
                        };

                        TaskFactory factory = new TaskFactory(scheduler);
                        Debug.WriteLine(string.Format("Start tasks in scheduler {0}", scheduler.Id));
                        Task t1 = factory.StartNew(work); Task t2 = factory.StartNew(work); Task t3 = factory.StartNew(work);
                        Task.WaitAll(t1, t2, t3);
                    }
                };

                for (int i = 0; i < 2; i++)
                {
                    tasks.Add(Task.Factory.StartNew(() => recursiveWork(2), CancellationToken.None, TaskCreationOptions.None, scheduler));
                }
            }

            // Wait for all tasks to complete, then complete the schedulers
            Task.WaitAll(tasks.ToArray());
            foreach (var cesp in cesps)
            {
                cesp.Complete();
                cesp.Completion.Wait();
            }
        }
			public InnerTaskScheduler (ConcurrentExclusiveSchedulerPair scheduler,
			                               ConcurrentQueue<Task> queue)
			{
				this.scheduler = scheduler;
				this.queue = queue;
			}
Example #24
0
        public static void TestCreationOptions(String ctorType)
        {
            ConcurrentExclusiveSchedulerPair schedPair = null;
            //Need to define the default values since these values are passed to the verification methods
            TaskScheduler scheduler = TaskScheduler.Default;
            int maxConcurrentLevel = Environment.ProcessorCount;

            //Based on input args, use one of the ctor overloads
            switch (ctorType.ToLower())
            {
                case "default":
                    schedPair = new ConcurrentExclusiveSchedulerPair();
                    break;
                case "scheduler":
                    schedPair = new ConcurrentExclusiveSchedulerPair(scheduler);
                    break;
                case "maxconcurrent":
                    maxConcurrentLevel = 2;
                    schedPair = new ConcurrentExclusiveSchedulerPair(scheduler, maxConcurrentLevel);
                    break;
                case "all":
                    maxConcurrentLevel = Int32.MaxValue;
                    schedPair = new ConcurrentExclusiveSchedulerPair(scheduler, -1/*MaxConcurrentLevel*/, -1/*MaxItemsPerTask*/); //-1 gets converted to Int32.MaxValue
                    break;
                default:
                    throw new NotImplementedException(String.Format("The option specified {0} to create the ConcurrentExclusiveSchedulerPair is invalid", ctorType));
            }

            //Create the factories that use the exclusive scheduler and the concurrent scheduler. We test to ensure
            //that the ConcurrentExclusiveSchedulerPair created are valid by scheduling work on them.
            TaskFactory writers = new TaskFactory(schedPair.ExclusiveScheduler);
            TaskFactory readers = new TaskFactory(schedPair.ConcurrentScheduler);

            List<Task> taskList = new List<Task>(); //Store all tasks created, to enable wait until all of them are finished

            // Schedule some dummy work that should be run with as much parallelism as possible
            for (int i = 0; i < 50; i++)
            {
                //In the current design, when there are no more tasks to execute, the Task used by concurrentexclusive scheduler dies
                //by sleeping we simulate some non trival work that takes time and causes the concurrentexclusive scheduler Task 
                //to stay around for addition work.
                taskList.Add(readers.StartNew(() => { new ManualResetEvent(false).WaitOne(10); }));
            }
            // Schedule work where each item must be run when no other items are running
            for (int i = 0; i < 10; i++) taskList.Add(writers.StartNew(() => { new ManualResetEvent(false).WaitOne(5); }));

            //Wait on the tasks to finish to ensure that the ConcurrentExclusiveSchedulerPair created can schedule and execute tasks without issues
            foreach (var item in taskList)
            {
                item.Wait();
            }

            //verify that maxconcurrency was respected.
            if (ctorType == "maxconcurrent")
            {
                Assert.Equal(maxConcurrentLevel, schedPair.ConcurrentScheduler.MaximumConcurrencyLevel);
            }
            Assert.Equal(1, schedPair.ExclusiveScheduler.MaximumConcurrencyLevel);

            //verify that the schedulers have not completed
            Assert.False(schedPair.Completion.IsCompleted, "The schedulers should not have completed as a completion request was not issued.");

            //complete the scheduler and make sure it shuts down successfully
            schedPair.Complete();
            schedPair.Completion.Wait();

            //make sure no additional work may be scheduled
            foreach (var schedPairScheduler in new TaskScheduler[] { schedPair.ConcurrentScheduler, schedPair.ExclusiveScheduler })
            {
                Exception caughtException = null;
                try
                {
                    Task.Factory.StartNew(() => { }, CancellationToken.None, TaskCreationOptions.None, schedPairScheduler);
                }
                catch (Exception exc)
                {
                    caughtException = exc;
                }
                Assert.True(
                    caughtException is TaskSchedulerException && caughtException.InnerException is InvalidOperationException,
                    "Queueing after completion should fail");
            }
        }
 public SchedulerDebuggerView(ConcurrentExclusiveSchedulerPair owner)
 {
     this.owner = owner;
 }
			public SchedulerDebuggerView (ConcurrentExclusiveSchedulerPair owner)
			{
				this.owner = owner;
			}
Example #27
0
 /// <summary>Initializes the debug view.</summary>
 /// <param name="pair">The pair being debugged.</param>
 public DebugView(ConcurrentExclusiveSchedulerPair pair)
 {
     Contract.Requires(pair != null, "Need a pair with which to construct the debug view.");
     m_pair = pair;
 }
Example #28
0
        public static void TaskContinuation()
        {
            int taskCount = Environment.ProcessorCount;
            int maxDOP = Int32.MaxValue;
            int maxNumberExecutionsPerTask = 1;
            int data = 0;

            Task[] allTasks = new Task[taskCount + 1];

            CancellationTokenSource[] cts = new CancellationTokenSource[taskCount + 1];
            for (int i = 0; i <= taskCount; i++)
            {
                cts[i] = new CancellationTokenSource();
            }

            CancellationTokenSource cts2 = new CancellationTokenSource();
            ConcurrentExclusiveSchedulerPair scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, maxDOP, maxNumberExecutionsPerTask);
            for (int i = 0; i <= taskCount; i++)
            {
                int j = i;
                allTasks[i] = new Task(() =>
                {
                    new TaskFactory(TaskScheduler.Current).StartNew(() => { }).
                    ContinueWith((task, o) =>
                    {
                        int d = (int)o;
                        Interlocked.Add(ref data, d);
                    }, j).
                    ContinueWith((task, o) =>
                    {
                        int d = (int)o;
                        Interlocked.Add(ref data, d);
                        cts[d].Cancel();
                        if (d <= taskCount)
                        {
                            throw new OperationCanceledException(cts[d].Token);
                        }
                        return "Done";
                    }, j, cts[j].Token).
                    ContinueWith((task, o) =>
                        {
                            int d = (int)o;
                            Interlocked.Add(ref data, d);
                        }, j, CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, TaskScheduler.Default).Wait(Int32.MaxValue - 1, cts2.Token);
                });

                allTasks[i].Start(scheduler.ConcurrentScheduler);
            }

            Task.WaitAll(allTasks, int.MaxValue - 1, CancellationToken.None);
            Debug.WriteLine("Tasks ended: result {0}", data);
            Task completion = scheduler.Completion;
            scheduler.Complete();
            completion.Wait();

            int expectedResult = 3 * taskCount * (taskCount + 1) / 2;
            Assert.Equal(expectedResult, data);

            Assert.NotEqual(TaskScheduler.Default.Id, scheduler.ConcurrentScheduler.Id);
            Assert.NotEqual(TaskScheduler.Default.Id, scheduler.ExclusiveScheduler.Id);
        }
 // Token: 0x06006EED RID: 28397 RVA: 0x0017DDB5 File Offset: 0x0017BFB5
 public DebugView(ConcurrentExclusiveSchedulerPair pair)
 {
     this.m_pair = pair;
 }