Beispiel #1
0
        public void TestTwoTasksRequestingResourcesBothShouldSucceed()
        {
            int numOfThreads = 2;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            Object     resource1 = new object();
            Object     resource2 = new object();
            List <int> list1     = new List <int>();
            List <int> list2     = new List <int>();
            Task       t1        = CreateTaskWithResourceLock(id: 1, token: token1, resource1: resource1, resource2: resource2, list1);
            Task       t2        = CreateTaskWithResourceLock(id: 2, token: token2, resource1: resource2, resource2: resource1, list2);

            taskScheduler.Register(t1, 5, 5000, token1);
            taskScheduler.Register(t2, 4, 5000, token2);

            t1.Start(taskScheduler);
            Task.Delay(500).Wait();
            t2.Start(taskScheduler);

            Task.Delay(5000).Wait();
            Assert.AreEqual(list1.Count, 2);
            Assert.AreEqual(list2.Count, 2);
        }
Beispiel #2
0
        private static void PreemptingExampleNonPreemptingSchedulerMultipleTasks()
        {
            int numOfThreads = 2;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreateNonPreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token3 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token4 = taskScheduler.GetExecutionToken();
            Task t1 = CreateTask(id: 1, token: token1);
            Task t2 = CreateTask(id: 2, token: token2);
            Task t3 = CreateTask(id: 3, token: token3);
            Task t4 = CreateTask(id: 4, token: token4);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);
            taskScheduler.Register(t3, 3, 2500, token3);
            taskScheduler.Register(t4, 2, 2500, token4);

            t1.Start(taskScheduler);
            t2.Start(taskScheduler);
            Task.Delay(1000).Wait();
            t3.Start(taskScheduler);
            t4.Start(taskScheduler);

            taskScheduler.FinishScheduling();
        }
Beispiel #3
0
        public void Test10TasksOn5ThreadsPreemptingEachOther()
        {
            int numOfThreads = 5;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token3  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token4  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token5  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token6  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token7  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token8  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token9  = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token10 = taskScheduler.GetExecutionToken();
            Object resource = new object();
            Task   t1       = CreateTaskWithResourceLock(id: 1, token: token1, resource: resource);
            Task   t2       = CreateTaskWithResourceLock(id: 2, token: token2, resource: resource);
            Task   t3       = CreateTaskWithResourceLock(id: 3, token: token3, resource: resource);
            Task   t4       = CreateTaskWithResourceLock(id: 4, token: token4, resource: resource);
            Task   t5       = CreateTaskWithResourceLock(id: 5, token: token5, resource: resource);
            Task   t6       = CreateTaskWithResourceLock(id: 6, token: token6, resource: resource);
            Task   t7       = CreateTaskWithResourceLock(id: 7, token: token7, resource: resource);
            Task   t8       = CreateTaskWithResourceLock(id: 8, token: token8, resource: resource);
            Task   t9       = CreateTaskWithResourceLock(id: 9, token: token9, resource: resource);
            Task   t10      = CreateTaskWithResourceLock(id: 10, token: token10, resource: resource);

            taskScheduler.Register(t1, 1, 2500, token1);
            taskScheduler.Register(t2, 2, 2500, token2);
            taskScheduler.Register(t3, 3, 2500, token3);
            taskScheduler.Register(t4, 4, 2500, token4);
            taskScheduler.Register(t5, 5, 2500, token5);
            taskScheduler.Register(t6, 6, 2500, token6);
            taskScheduler.Register(t7, 7, 2500, token7);
            taskScheduler.Register(t8, 8, 2500, token8);
            taskScheduler.Register(t9, 9, 2500, token9);
            taskScheduler.Register(t10, 10, 2500, token10);

            t1.Start(taskScheduler);
            t2.Start(taskScheduler);
            t3.Start(taskScheduler);
            t4.Start(taskScheduler);
            t5.Start(taskScheduler);
            t6.Start(taskScheduler);
            t7.Start(taskScheduler);
            t8.Start(taskScheduler);
            t9.Start(taskScheduler);
            t10.Start(taskScheduler);
            Task.Delay(15000).Wait();
            Assert.IsTrue(t1.IsCompleted);
            Assert.IsTrue(t2.IsCompleted);
            Assert.IsTrue(t3.IsCompleted);
            Assert.IsTrue(t4.IsCompleted);
            Assert.IsTrue(t5.IsCompleted);
            Assert.IsTrue(t6.IsCompleted);
            Assert.IsTrue(t7.IsCompleted);
            Assert.IsTrue(t8.IsCompleted);
            Assert.IsTrue(t9.IsCompleted);
            Assert.IsTrue(t10.IsCompleted);
        }
Beispiel #4
0
        public void TestThreeTasksOnTwoThreadsPreemptingEachOther()
        {
            int numOfThreads = 2;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token3 = taskScheduler.GetExecutionToken();
            Object resource = new object();
            Task   t1       = CreateTaskWithResourceLock(id: 1, token: token1, resource: resource);
            Task   t2       = CreateTaskWithResourceLock(id: 2, token: token2, resource: resource);
            Task   t3       = CreateTask(id: 3, token: token3);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);
            taskScheduler.Register(t3, 3, 2500, token3);

            t1.Start(taskScheduler);
            Task.Delay(500).Wait();
            t2.Start(taskScheduler);
            t3.Start(taskScheduler);

            Task.Delay(5000).Wait();
            Assert.AreEqual(taskScheduler.CurrentlyExecutingTasksCount(), 0);
        }
Beispiel #5
0
        private static void DeadlockDetectionExample()
        {
            int numOfThreads = 2;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token3 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token4 = taskScheduler.GetExecutionToken();
            Object resource1 = new object();
            Object resource2 = new object();
            Task   t1        = CreateTaskWithResourceLock(id: 1, token: token1, resource1: resource1, resource2: resource2);
            Task   t2        = CreateTaskWithResourceLock(id: 2, token: token2, resource1: resource2, resource2: resource1);
            Task   t3        = CreateTaskWithResourceLock(id: 3, token: token3, resource1: resource1, resource2: resource2);
            Task   t4        = CreateTaskWithResourceLock(id: 4, token: token4, resource1: resource2, resource2: resource1);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);
            taskScheduler.Register(t3, 3, 2500, token3);
            taskScheduler.Register(t4, 2, 2500, token4);

            t1.Start(taskScheduler);
            t2.Start(taskScheduler);
            t3.Start(taskScheduler);
            t4.Start(taskScheduler);
        }
 internal TaskWantsToUnlockResourceEvent(SimpleTaskScheduler scheduler, ExecutionToken taskToken, EventWaitHandle taskNotifier, object resource)
 {
     this.scheduler    = scheduler;
     this.taskToken    = taskToken;
     this.taskNotifier = taskNotifier;
     this.resource     = resource;
 }
Beispiel #7
0
        public void TestCreationOfNonPreemptiveSimpleTaskSchedulerWithTwoThreads()
        {
            int numberOfThreads    = 2;
            SimpleTaskScheduler st = SimpleTaskScheduler.CreateNonPreemptive(numberOfThreads);

            Assert.AreEqual(numberOfThreads, st.GetMaxParallelTasks());
            Assert.AreEqual(false, st.IsSchedulerPreemptive());
        }
Beispiel #8
0
        private static void BaseClassExample()
        {
            int           numOfThreads  = 1;
            TaskScheduler taskScheduler = SimpleTaskScheduler.CreateNonPreemptive(numOfThreads);
            Task          t             = CreateTask(id: 1);

            t.Start(taskScheduler);

            ((SimpleTaskScheduler)taskScheduler).FinishScheduling();
        }
Beispiel #9
0
        public void TestCreationOfPreemptiveSimpleTaskSchedulerWithMinusThreeThreads()
        {
            int numberOfThreads = -3;

            try
            {
                SimpleTaskScheduler st = SimpleTaskScheduler.CreatePreemptive(numberOfThreads);
                Assert.Fail();
            }
            catch (ArgumentOutOfRangeException ex) { }
        }
Beispiel #10
0
        public void TestSchedulingOfPreemptiveUsingBaseClassShouldFailQueueing()
        {
            int numOfThreads = 2;
            SimpleTaskScheduler taskScheduler     = SimpleTaskScheduler.CreatePreemptive(numOfThreads);
            TaskScheduler       baseTaskScheduler = taskScheduler;
            Task t = CreateTask(id: 1, token: taskScheduler.GetExecutionToken());

            t.Start(baseTaskScheduler);

            Assert.IsFalse(taskScheduler.IsTaskCurrentlyExecuting(t));
        }
Beispiel #11
0
        public void TestSchedulingOfNonPreemptiveUsingBaseClassShouldSucceedQueueing()
        {
            int numOfThreads = 2;
            SimpleTaskScheduler taskScheduler     = SimpleTaskScheduler.CreateNonPreemptive(numOfThreads);
            TaskScheduler       baseTaskScheduler = taskScheduler;
            Task t = CreateTask(id: 1, token: taskScheduler.GetExecutionToken());

            t.Start(baseTaskScheduler);

            Task.Delay(500).Wait();
            Assert.IsTrue(taskScheduler.IsTaskCurrentlyExecuting(t));
        }
Beispiel #12
0
        public void TestTwoTasksWithNoResourceLocking()
        {
            int numOfThreads = 1;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            Task t1 = CreateTask(id: 1, token: token1);
            Task t2 = CreateTask(id: 2, token: token2);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);

            t1.Start(taskScheduler);
            Task.Delay(500).Wait();
            t2.Start(taskScheduler);
            Assert.AreEqual(taskScheduler.CurrentlyExecutingTasksCount(), 1);
        }
Beispiel #13
0
        private static void SingleThreadPreemptingExampleNonPreemptingScheduler()
        {
            int numOfThreads = 1;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreateNonPreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            Task t1 = CreateTask(id: 1, token: token1);
            Task t2 = CreateTask(id: 2, token: token2);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);

            t1.Start(taskScheduler);
            Task.Delay(1000).Wait();
            t2.Start(taskScheduler);
            taskScheduler.FinishScheduling();
        }
Beispiel #14
0
        private static void PriorityInversionExample2()
        {
            int numOfThreads = 1;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            Object resource = new Object();
            Task   t1       = CreateTaskWithResourceLockAndUnlockResource(id: 1, token: token1, resource);
            Task   t2       = CreateTaskWithResourceLockAndUnlockResource(id: 2, token: token2, resource);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);

            t1.Start(taskScheduler);
            Task.Delay(1000).Wait();
            t2.Start(taskScheduler);
            taskScheduler.FinishScheduling();
        }
Beispiel #15
0
        public void TestTwoTasksWithOneResourceLockingAndGettingMaxPriority()
        {
            int numOfThreads = 1;
            SimpleTaskScheduler taskScheduler = SimpleTaskScheduler.CreatePreemptive(numOfThreads);

            SimpleTaskScheduler.ExecutionToken token1 = taskScheduler.GetExecutionToken();
            SimpleTaskScheduler.ExecutionToken token2 = taskScheduler.GetExecutionToken();
            Task t1 = CreateTaskWithResourceLock(id: 1, token: token1, resource: new object());;
            Task t2 = CreateTask(id: 2, token: token2);

            taskScheduler.Register(t1, 5, 2500, token1);
            taskScheduler.Register(t2, 4, 2500, token2);

            t1.Start(taskScheduler);
            Task.Delay(500).Wait();
            t2.Start(taskScheduler);
            Task.Delay(2000).Wait();

            Assert.IsTrue(taskScheduler.IsTaskCurrentlyExecuting(t2));
        }
 internal TaskCompletedEvent(SimpleTaskScheduler scheduler, Task completedTask)
 {
     this.scheduler     = scheduler;
     this.completedTask = completedTask;
 }
 internal CancelTaskIfExistsEvent(SimpleTaskScheduler scheduler, Task taskToBeCancelled)
 {
     this.scheduler         = scheduler;
     this.taskToBeCancelled = taskToBeCancelled;
 }
 internal ScheduleTasksEvent(SimpleTaskScheduler scheduler)
 {
     this.scheduler = scheduler;
 }
Beispiel #19
0
        //[Fact(Skip = "Outerloop")]
        public void RunActionBlockConformanceTests()
        {
            // SYNC
            // Do everything twice - once through OfferMessage and Once through Post
            for (FeedMethod feedMethod = FeedMethod._First; feedMethod < FeedMethod._Count; feedMethod++)
            {
                Func <DataflowBlockOptions, TargetProperties <int> > actionBlockFactory =
                    options =>
                {
                    ITargetBlock <int> target = new ActionBlock <int>(i => TrackCaptures(i), (ExecutionDataflowBlockOptions)options);
                    return(new TargetProperties <int> {
                        Target = target, Capturer = target, ErrorVerifyable = true
                    });
                };

                CancellationTokenSource cancellationSource = new CancellationTokenSource();
                var defaultOptions = new ExecutionDataflowBlockOptions();
                var dopOptions     = new ExecutionDataflowBlockOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                };
                var mptOptions = new ExecutionDataflowBlockOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 1
                };
                var cancellationOptions = new ExecutionDataflowBlockOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 1, CancellationToken = cancellationSource.Token
                };
                var spscOptions = new ExecutionDataflowBlockOptions {
                    SingleProducerConstrained = true
                };
                var spscMptOptions = new ExecutionDataflowBlockOptions {
                    SingleProducerConstrained = true, MaxMessagesPerTask = 10
                };

                Assert.True(FeedTarget(actionBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, dopOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 1, Intervention.Complete, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, cancellationOptions, 1, Intervention.Cancel, cancellationSource, feedMethod, true));

                Assert.True(FeedTarget(actionBlockFactory, spscOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, spscOptions, 1, Intervention.Complete, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, spscMptOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, spscMptOptions, 1, Intervention.Complete, null, feedMethod, true));
            }

            // Test scheduler usage
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    var sts = new SimpleTaskScheduler();

                    var options = new ExecutionDataflowBlockOptions {
                        TaskScheduler = sts, MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded, MaxMessagesPerTask = 1
                    };
                    if (trial == 0)
                    {
                        options.SingleProducerConstrained = true;
                    }

                    var ab = new ActionBlock <int>(i => localPassed &= TaskScheduler.Current.Id == sts.Id, options);
                    for (int i = 0; i < 2; i++)
                    {
                        ab.Post(i);
                    }
                    ab.Complete();
                    ab.Completion.Wait();
                }

                Assert.True(localPassed, string.Format("{0}: Correct scheduler usage", localPassed ? "Success" : "Failure"));
            }

            // Test count
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    var barrier1 = new Barrier(2);
                    var barrier2 = new Barrier(2);
                    var ab       = new ActionBlock <int>(i =>
                    {
                        barrier1.SignalAndWait();
                        barrier2.SignalAndWait();
                    }, new ExecutionDataflowBlockOptions {
                        SingleProducerConstrained = (trial == 0)
                    });
                    for (int iter = 0; iter < 2; iter++)
                    {
                        for (int i = 1; i <= 2; i++)
                        {
                            ab.Post(i);
                        }
                        for (int i = 1; i >= 0; i--)
                        {
                            barrier1.SignalAndWait();
                            localPassed &= i == ab.InputCount;
                            barrier2.SignalAndWait();
                        }
                    }
                }

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

            // Test ordering
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    int prev = -1;
                    var ab   = new ActionBlock <int>(i =>
                    {
                        if (prev + 1 != i)
                        {
                            localPassed &= false;
                        }
                        prev = i;
                    }, new ExecutionDataflowBlockOptions {
                        SingleProducerConstrained = (trial == 0)
                    });
                    for (int i = 0; i < 2; i++)
                    {
                        ab.Post(i);
                    }
                    ab.Complete();
                    ab.Completion.Wait();
                }

                Assert.True(localPassed, string.Format("{0}: Correct ordering", localPassed ? "Success" : "Failure"));
            }

            // Test non-greedy
            {
                bool localPassed = true;
                var  barrier     = new Barrier(2);
                var  ab          = new ActionBlock <int>(i =>
                {
                    barrier.SignalAndWait();
                }, new ExecutionDataflowBlockOptions {
                    BoundedCapacity = 1
                });
                ab.SendAsync(1);
                Task.Delay(200).Wait();
                var sa2 = ab.SendAsync(2);
                localPassed &= !sa2.IsCompleted;
                barrier.SignalAndWait(); // for SendAsync(1)
                barrier.SignalAndWait(); // for SendAsync(2)
                localPassed &= sa2.Wait(100);
                int total = 0;
                ab = new ActionBlock <int>(i =>
                {
                    Interlocked.Add(ref total, i);
                    Task.Delay(1).Wait();
                }, new ExecutionDataflowBlockOptions {
                    BoundedCapacity = 1
                });
                for (int i = 1; i <= 100; i++)
                {
                    ab.SendAsync(i);
                }
                SpinWait.SpinUntil(() => total == ((100 * 101) / 2), 30000);
                localPassed &= total == ((100 * 101) / 2);
                Assert.True(localPassed, string.Format("total={0} (must be {1})", total, (100 * 101) / 2));
                Assert.True(localPassed, string.Format("{0}: Non-greedy support", localPassed ? "Success" : "Failure"));
            }

            // Test that OperationCanceledExceptions are ignored
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    int sumOfOdds = 0;
                    var ab        = new ActionBlock <int>(i =>
                    {
                        if ((i % 2) == 0)
                        {
                            throw new OperationCanceledException();
                        }
                        sumOfOdds += i;
                    }, new ExecutionDataflowBlockOptions {
                        SingleProducerConstrained = (trial == 0)
                    });
                    for (int i = 0; i < 4; i++)
                    {
                        ab.Post(i);
                    }
                    ab.Complete();
                    ab.Completion.Wait();
                    localPassed = sumOfOdds == (1 + 3);
                }

                Assert.True(localPassed, string.Format("{0}: OperationCanceledExceptions are ignored", localPassed ? "Success" : "Failure"));
            }

            // Test using a precanceled token
            {
                bool localPassed = true;
                try
                {
                    var cts = new CancellationTokenSource();
                    cts.Cancel();
                    var dbo = new ExecutionDataflowBlockOptions {
                        CancellationToken = cts.Token
                    };
                    var ab = new ActionBlock <int>(i => { }, dbo);

                    localPassed &= ab.Post(42) == false;
                    localPassed &= ab.InputCount == 0;
                    localPassed &= ab.Completion != null;
                    ab.Complete();
                }
                catch (Exception)
                {
                    localPassed = false;
                }

                Assert.True(localPassed, string.Format("{0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure"));
            }

            // Test faulting
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    var ab = new ActionBlock <int>(i => { throw new InvalidOperationException(); },
                                                   new ExecutionDataflowBlockOptions {
                        SingleProducerConstrained = (trial == 0)
                    });
                    ab.Post(42);
                    ab.Post(1);
                    ab.Post(2);
                    ab.Post(3);
                    try { localPassed &= ab.Completion.Wait(5000); }
                    catch { }
                    localPassed &= ab.Completion.IsFaulted;
                    localPassed &= SpinWait.SpinUntil(() => ab.InputCount == 0, 500);
                    localPassed &= ab.Post(4) == false;
                }

                Assert.True(localPassed, string.Format("{0}: Faulted handled correctly", localPassed ? "Success" : "Failure"));
            }

            // ASYNC (a copy of the sync but with constructors returning Task instead of void

            // Do everything twice - once through OfferMessage and Once through Post
            for (FeedMethod feedMethod = FeedMethod._First; feedMethod < FeedMethod._Count; feedMethod++)
            {
                Func <DataflowBlockOptions, TargetProperties <int> > actionBlockFactory =
                    options =>
                {
                    ITargetBlock <int> target = new ActionBlock <int>(i => TrackCapturesAsync(i), (ExecutionDataflowBlockOptions)options);
                    return(new TargetProperties <int> {
                        Target = target, Capturer = target, ErrorVerifyable = true
                    });
                };
                CancellationTokenSource cancellationSource = new CancellationTokenSource();
                var defaultOptions = new ExecutionDataflowBlockOptions();
                var dopOptions     = new ExecutionDataflowBlockOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                };
                var mptOptions = new ExecutionDataflowBlockOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 10
                };
                var cancellationOptions = new ExecutionDataflowBlockOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 100, CancellationToken = cancellationSource.Token
                };

                Assert.True(FeedTarget(actionBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, defaultOptions, 10, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, dopOptions, 1000, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 10000, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 10000, Intervention.Complete, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, cancellationOptions, 10000, Intervention.Cancel, cancellationSource, feedMethod, true));
            }

            // Test scheduler usage
            {
                bool localPassed = true;
                var  sts         = new SimpleTaskScheduler();
                var  ab          = new ActionBlock <int>(i =>
                {
                    localPassed &= TaskScheduler.Current.Id == sts.Id;
                    return(Task.Factory.StartNew(() => { }));
                }, new ExecutionDataflowBlockOptions {
                    TaskScheduler = sts, MaxDegreeOfParallelism = -1, MaxMessagesPerTask = 10
                });
                for (int i = 0; i < 2; i++)
                {
                    ab.Post(i);
                }
                ab.Complete();
                ab.Completion.Wait();
                Assert.True(localPassed, string.Format("{0}: Correct scheduler usage", localPassed ? "Success" : "Failure"));
            }

            // Test count
            {
                bool localPassed = true;
                var  barrier1    = new Barrier(2);
                var  barrier2    = new Barrier(2);
                var  ab          = new ActionBlock <int>(i => Task.Factory.StartNew(() =>
                {
                    barrier1.SignalAndWait();
                    barrier2.SignalAndWait();
                }));
                for (int iter = 0; iter < 2; iter++)
                {
                    for (int i = 1; i <= 2; i++)
                    {
                        ab.Post(i);
                    }
                    for (int i = 1; i >= 0; i--)
                    {
                        barrier1.SignalAndWait();
                        localPassed &= i == ab.InputCount;
                        barrier2.SignalAndWait();
                    }
                }
                Assert.True(localPassed, string.Format("{0}: InputCount", localPassed ? "Success" : "Failure"));
            }

            // Test ordering
            {
                bool localPassed = true;
                int  prev        = -1;
                var  ab          = new ActionBlock <int>(i =>
                {
                    return(Task.Factory.StartNew(() =>
                    {
                        if (prev + 1 != i)
                        {
                            localPassed &= false;
                        }
                        prev = i;
                    }));
                });
                for (int i = 0; i < 2; i++)
                {
                    ab.Post(i);
                }
                ab.Complete();
                ab.Completion.Wait();
                Assert.True(localPassed, string.Format("{0}: Correct ordering", localPassed ? "Success" : "Failure"));
            }

            // Test non-greedy
            {
                bool localPassed = true;
                var  barrier     = new Barrier(2);
                var  ab          = new ActionBlock <int>(i =>
                {
                    return(Task.Factory.StartNew(() =>
                    {
                        barrier.SignalAndWait();
                    }));
                }, new ExecutionDataflowBlockOptions {
                    BoundedCapacity = 1
                });
                ab.SendAsync(1);
                Task.Delay(200).Wait();
                var sa2 = ab.SendAsync(2);
                localPassed &= !sa2.IsCompleted;
                barrier.SignalAndWait(); // for SendAsync(1)
                barrier.SignalAndWait(); // for SendAsync(2)
                localPassed &= sa2.Wait(100);
                int total = 0;
                ab = new ActionBlock <int>(i =>
                {
                    return(Task.Factory.StartNew(() =>
                    {
                        Interlocked.Add(ref total, i);
                        Task.Delay(1).Wait();
                    }));
                }, new ExecutionDataflowBlockOptions {
                    BoundedCapacity = 1
                });
                for (int i = 1; i <= 100; i++)
                {
                    ab.SendAsync(i);
                }
                SpinWait.SpinUntil(() => total == ((100 * 101) / 2), 30000);
                localPassed &= total == ((100 * 101) / 2);
                Assert.True(localPassed, string.Format("total={0} (must be {1})", total, (100 * 101) / 2));
                Assert.True(localPassed, string.Format("{0}: Non-greedy support", localPassed ? "Success" : "Failure"));
            }

            // Test that OperationCanceledExceptions are ignored
            {
                bool localPassed = true;
                int  sumOfOdds   = 0;
                var  ab          = new ActionBlock <int>(i =>
                {
                    if ((i % 2) == 0)
                    {
                        throw new OperationCanceledException();
                    }
                    return(Task.Factory.StartNew(() => { sumOfOdds += i; }));
                });
                for (int i = 0; i < 4; i++)
                {
                    ab.Post(i);
                }
                ab.Complete();
                ab.Completion.Wait();
                localPassed = sumOfOdds == (1 + 3);
                Assert.True(localPassed, string.Format("{0}: OperationCanceledExceptions are ignored", localPassed ? "Success" : "Failure"));
            }

            // Test that null task is ignored
            {
                bool localPassed = true;
                int  sumOfOdds   = 0;
                var  ab          = new ActionBlock <int>(i =>
                {
                    if ((i % 2) == 0)
                    {
                        return(null);
                    }
                    return(Task.Factory.StartNew(() => { sumOfOdds += i; }));
                });
                for (int i = 0; i < 4; i++)
                {
                    ab.Post(i);
                }
                ab.Complete();
                ab.Completion.Wait();
                localPassed = sumOfOdds == (1 + 3);
                Assert.True(localPassed, string.Format("{0}: null tasks are ignored", localPassed ? "Success" : "Failure"));
            }

            // Test faulting from the delegate
            {
                bool localPassed = true;
                var  ab          = new ActionBlock <int>(new Func <int, Task>(i => { throw new InvalidOperationException(); }));
                ab.Post(42);
                ab.Post(1);
                ab.Post(2);
                ab.Post(3);
                try { localPassed &= ab.Completion.Wait(100); }
                catch { }
                localPassed &= ab.Completion.IsFaulted;
                localPassed &= SpinWait.SpinUntil(() => ab.InputCount == 0, 500);
                localPassed &= ab.Post(4) == false;
                Assert.True(localPassed, string.Format("{0}: Faulted from delegate handled correctly", localPassed ? "Success" : "Failure"));
            }

            // Test faulting from the task
            {
                bool localPassed = true;
                var  ab          = new ActionBlock <int>(i => Task.Factory.StartNew(() => { throw new InvalidOperationException(); }));
                ab.Post(42);
                ab.Post(1);
                ab.Post(2);
                ab.Post(3);
                try { localPassed &= ab.Completion.Wait(100); }
                catch { }
                localPassed &= ab.Completion.IsFaulted;
                localPassed &= SpinWait.SpinUntil(() => ab.InputCount == 0, 500);
                localPassed &= ab.Post(4) == false;
                Assert.True(localPassed, string.Format("{0}: Faulted from task handled correctly", localPassed ? "Success" : "Failure"));
            }
        }
Beispiel #20
0
        //[Fact(Skip = "Outerloop")]
        public void RunActionBlockConformanceTests()
        {
            // SYNC
            // Do everything twice - once through OfferMessage and Once through Post
            for (FeedMethod feedMethod = FeedMethod._First; feedMethod < FeedMethod._Count; feedMethod++)
            {
                Func<DataflowBlockOptions, TargetProperties<int>> actionBlockFactory =
                    options =>
                    {
                        ITargetBlock<int> target = new ActionBlock<int>(i => TrackCaptures(i), (ExecutionDataflowBlockOptions)options);
                        return new TargetProperties<int> { Target = target, Capturer = target, ErrorVerifyable = true };
                    };

                CancellationTokenSource cancellationSource = new CancellationTokenSource();
                var defaultOptions = new ExecutionDataflowBlockOptions();
                var dopOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
                var mptOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 1 };
                var cancellationOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 1, CancellationToken = cancellationSource.Token };
                var spscOptions = new ExecutionDataflowBlockOptions { SingleProducerConstrained = true };
                var spscMptOptions = new ExecutionDataflowBlockOptions { SingleProducerConstrained = true, MaxMessagesPerTask = 10 };

                Assert.True(FeedTarget(actionBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, dopOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 1, Intervention.Complete, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, cancellationOptions, 1, Intervention.Cancel, cancellationSource, feedMethod, true));

                Assert.True(FeedTarget(actionBlockFactory, spscOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, spscOptions, 1, Intervention.Complete, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, spscMptOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, spscMptOptions, 1, Intervention.Complete, null, feedMethod, true));
            }

            // Test scheduler usage
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    var sts = new SimpleTaskScheduler();

                    var options = new ExecutionDataflowBlockOptions { TaskScheduler = sts, MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded, MaxMessagesPerTask = 1 };
                    if (trial == 0) options.SingleProducerConstrained = true;

                    var ab = new ActionBlock<int>(i => localPassed &= TaskScheduler.Current.Id == sts.Id, options);
                    for (int i = 0; i < 2; i++) ab.Post(i);
                    ab.Complete();
                    ab.Completion.Wait();
                }

                Assert.True(localPassed, string.Format("{0}: Correct scheduler usage", localPassed ? "Success" : "Failure"));
            }

            // Test count
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    var barrier1 = new Barrier(2);
                    var barrier2 = new Barrier(2);
                    var ab = new ActionBlock<int>(i =>
                    {
                        barrier1.SignalAndWait();
                        barrier2.SignalAndWait();
                    }, new ExecutionDataflowBlockOptions { SingleProducerConstrained = (trial == 0) });
                    for (int iter = 0; iter < 2; iter++)
                    {
                        for (int i = 1; i <= 2; i++) ab.Post(i);
                        for (int i = 1; i >= 0; i--)
                        {
                            barrier1.SignalAndWait();
                            localPassed &= i == ab.InputCount;
                            barrier2.SignalAndWait();
                        }
                    }
                }

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

            // Test ordering
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    int prev = -1;
                    var ab = new ActionBlock<int>(i =>
                    {
                        if (prev + 1 != i) localPassed &= false;
                        prev = i;
                    }, new ExecutionDataflowBlockOptions { SingleProducerConstrained = (trial == 0) });
                    for (int i = 0; i < 2; i++) ab.Post(i);
                    ab.Complete();
                    ab.Completion.Wait();
                }

                Assert.True(localPassed, string.Format("{0}: Correct ordering", localPassed ? "Success" : "Failure"));
            }

            // Test non-greedy
            {
                bool localPassed = true;
                var barrier = new Barrier(2);
                var ab = new ActionBlock<int>(i =>
                {
                    barrier.SignalAndWait();
                }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1 });
                ab.SendAsync(1);
                Task.Delay(200).Wait();
                var sa2 = ab.SendAsync(2);
                localPassed &= !sa2.IsCompleted;
                barrier.SignalAndWait(); // for SendAsync(1)
                barrier.SignalAndWait(); // for SendAsync(2)
                localPassed &= sa2.Wait(100);
                int total = 0;
                ab = new ActionBlock<int>(i =>
                {
                    Interlocked.Add(ref total, i);
                    Task.Delay(1).Wait();
                }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1 });
                for (int i = 1; i <= 100; i++) ab.SendAsync(i);
                SpinWait.SpinUntil(() => total == ((100 * 101) / 2), 30000);
                localPassed &= total == ((100 * 101) / 2);
                Assert.True(localPassed, string.Format("total={0} (must be {1})", total, (100 * 101) / 2));
                Assert.True(localPassed, string.Format("{0}: Non-greedy support", localPassed ? "Success" : "Failure"));
            }

            // Test that OperationCanceledExceptions are ignored
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    int sumOfOdds = 0;
                    var ab = new ActionBlock<int>(i =>
                    {
                        if ((i % 2) == 0) throw new OperationCanceledException();
                        sumOfOdds += i;
                    }, new ExecutionDataflowBlockOptions { SingleProducerConstrained = (trial == 0) });
                    for (int i = 0; i < 4; i++) ab.Post(i);
                    ab.Complete();
                    ab.Completion.Wait();
                    localPassed = sumOfOdds == (1 + 3);
                }

                Assert.True(localPassed, string.Format("{0}: OperationCanceledExceptions are ignored", localPassed ? "Success" : "Failure"));
            }

            // Test using a precanceled token
            {
                bool localPassed = true;
                try
                {
                    var cts = new CancellationTokenSource();
                    cts.Cancel();
                    var dbo = new ExecutionDataflowBlockOptions { CancellationToken = cts.Token };
                    var ab = new ActionBlock<int>(i => { }, dbo);

                    localPassed &= ab.Post(42) == false;
                    localPassed &= ab.InputCount == 0;
                    localPassed &= ab.Completion != null;
                    ab.Complete();
                }
                catch (Exception)
                {
                    localPassed = false;
                }

                Assert.True(localPassed, string.Format("{0}: Precanceled tokens work correctly", localPassed ? "Success" : "Failure"));
            }

            // Test faulting
            {
                bool localPassed = true;
                for (int trial = 0; trial < 2; trial++)
                {
                    var ab = new ActionBlock<int>(i => { throw new InvalidOperationException(); },
                        new ExecutionDataflowBlockOptions { SingleProducerConstrained = (trial == 0) });
                    ab.Post(42);
                    ab.Post(1);
                    ab.Post(2);
                    ab.Post(3);
                    try { localPassed &= ab.Completion.Wait(5000); }
                    catch { }
                    localPassed &= ab.Completion.IsFaulted;
                    localPassed &= SpinWait.SpinUntil(() => ab.InputCount == 0, 500);
                    localPassed &= ab.Post(4) == false;
                }

                Assert.True(localPassed, string.Format("{0}: Faulted handled correctly", localPassed ? "Success" : "Failure"));
            }

            // ASYNC (a copy of the sync but with constructors returning Task instead of void

            // Do everything twice - once through OfferMessage and Once through Post
            for (FeedMethod feedMethod = FeedMethod._First; feedMethod < FeedMethod._Count; feedMethod++)
            {
                Func<DataflowBlockOptions, TargetProperties<int>> actionBlockFactory =
                    options =>
                    {
                        ITargetBlock<int> target = new ActionBlock<int>(i => TrackCapturesAsync(i), (ExecutionDataflowBlockOptions)options);
                        return new TargetProperties<int> { Target = target, Capturer = target, ErrorVerifyable = true };
                    };
                CancellationTokenSource cancellationSource = new CancellationTokenSource();
                var defaultOptions = new ExecutionDataflowBlockOptions();
                var dopOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
                var mptOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 10 };
                var cancellationOptions = new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, MaxMessagesPerTask = 100, CancellationToken = cancellationSource.Token };

                Assert.True(FeedTarget(actionBlockFactory, defaultOptions, 1, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, defaultOptions, 10, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, dopOptions, 1000, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 10000, Intervention.None, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, mptOptions, 10000, Intervention.Complete, null, feedMethod, true));
                Assert.True(FeedTarget(actionBlockFactory, cancellationOptions, 10000, Intervention.Cancel, cancellationSource, feedMethod, true));
            }

            // Test scheduler usage
            {
                bool localPassed = true;
                var sts = new SimpleTaskScheduler();
                var ab = new ActionBlock<int>(i =>
                    {
                        localPassed &= TaskScheduler.Current.Id == sts.Id;
                        return Task.Factory.StartNew(() => { });
                    }, new ExecutionDataflowBlockOptions { TaskScheduler = sts, MaxDegreeOfParallelism = -1, MaxMessagesPerTask = 10 });
                for (int i = 0; i < 2; i++) ab.Post(i);
                ab.Complete();
                ab.Completion.Wait();
                Assert.True(localPassed, string.Format("{0}: Correct scheduler usage", localPassed ? "Success" : "Failure"));
            }

            // Test count
            {
                bool localPassed = true;
                var barrier1 = new Barrier(2);
                var barrier2 = new Barrier(2);
                var ab = new ActionBlock<int>(i => Task.Factory.StartNew(() =>
                {
                    barrier1.SignalAndWait();
                    barrier2.SignalAndWait();
                }));
                for (int iter = 0; iter < 2; iter++)
                {
                    for (int i = 1; i <= 2; i++) ab.Post(i);
                    for (int i = 1; i >= 0; i--)
                    {
                        barrier1.SignalAndWait();
                        localPassed &= i == ab.InputCount;
                        barrier2.SignalAndWait();
                    }
                }
                Assert.True(localPassed, string.Format("{0}: InputCount", localPassed ? "Success" : "Failure"));
            }

            // Test ordering
            {
                bool localPassed = true;
                int prev = -1;
                var ab = new ActionBlock<int>(i =>
                {
                    return Task.Factory.StartNew(() =>
                    {
                        if (prev + 1 != i) localPassed &= false;
                        prev = i;
                    });
                });
                for (int i = 0; i < 2; i++) ab.Post(i);
                ab.Complete();
                ab.Completion.Wait();
                Assert.True(localPassed, string.Format("{0}: Correct ordering", localPassed ? "Success" : "Failure"));
            }

            // Test non-greedy
            {
                bool localPassed = true;
                var barrier = new Barrier(2);
                var ab = new ActionBlock<int>(i =>
                {
                    return Task.Factory.StartNew(() =>
                    {
                        barrier.SignalAndWait();
                    });
                }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1 });
                ab.SendAsync(1);
                Task.Delay(200).Wait();
                var sa2 = ab.SendAsync(2);
                localPassed &= !sa2.IsCompleted;
                barrier.SignalAndWait(); // for SendAsync(1)
                barrier.SignalAndWait(); // for SendAsync(2)
                localPassed &= sa2.Wait(100);
                int total = 0;
                ab = new ActionBlock<int>(i =>
                {
                    return Task.Factory.StartNew(() =>
                    {
                        Interlocked.Add(ref total, i);
                        Task.Delay(1).Wait();
                    });
                }, new ExecutionDataflowBlockOptions { BoundedCapacity = 1 });
                for (int i = 1; i <= 100; i++) ab.SendAsync(i);
                SpinWait.SpinUntil(() => total == ((100 * 101) / 2), 30000);
                localPassed &= total == ((100 * 101) / 2);
                Assert.True(localPassed, string.Format("total={0} (must be {1})", total, (100 * 101) / 2));
                Assert.True(localPassed, string.Format("{0}: Non-greedy support", localPassed ? "Success" : "Failure"));
            }

            // Test that OperationCanceledExceptions are ignored
            {
                bool localPassed = true;
                int sumOfOdds = 0;
                var ab = new ActionBlock<int>(i =>
                {
                    if ((i % 2) == 0) throw new OperationCanceledException();
                    return Task.Factory.StartNew(() => { sumOfOdds += i; });
                });
                for (int i = 0; i < 4; i++) ab.Post(i);
                ab.Complete();
                ab.Completion.Wait();
                localPassed = sumOfOdds == (1 + 3);
                Assert.True(localPassed, string.Format("{0}: OperationCanceledExceptions are ignored", localPassed ? "Success" : "Failure"));
            }

            // Test that null task is ignored
            {
                bool localPassed = true;
                int sumOfOdds = 0;
                var ab = new ActionBlock<int>(i =>
                {
                    if ((i % 2) == 0) return null;
                    return Task.Factory.StartNew(() => { sumOfOdds += i; });
                });
                for (int i = 0; i < 4; i++) ab.Post(i);
                ab.Complete();
                ab.Completion.Wait();
                localPassed = sumOfOdds == (1 + 3);
                Assert.True(localPassed, string.Format("{0}: null tasks are ignored", localPassed ? "Success" : "Failure"));
            }

            // Test faulting from the delegate
            {
                bool localPassed = true;
                var ab = new ActionBlock<int>(new Func<int, Task>(i => { throw new InvalidOperationException(); }));
                ab.Post(42);
                ab.Post(1);
                ab.Post(2);
                ab.Post(3);
                try { localPassed &= ab.Completion.Wait(100); }
                catch { }
                localPassed &= ab.Completion.IsFaulted;
                localPassed &= SpinWait.SpinUntil(() => ab.InputCount == 0, 500);
                localPassed &= ab.Post(4) == false;
                Assert.True(localPassed, string.Format("{0}: Faulted from delegate handled correctly", localPassed ? "Success" : "Failure"));
            }

            // Test faulting from the task
            {
                bool localPassed = true;
                var ab = new ActionBlock<int>(i => Task.Factory.StartNew(() => { throw new InvalidOperationException(); }));
                ab.Post(42);
                ab.Post(1);
                ab.Post(2);
                ab.Post(3);
                try { localPassed &= ab.Completion.Wait(100); }
                catch { }
                localPassed &= ab.Completion.IsFaulted;
                localPassed &= SpinWait.SpinUntil(() => ab.InputCount == 0, 500);
                localPassed &= ab.Post(4) == false;
                Assert.True(localPassed, string.Format("{0}: Faulted from task handled correctly", localPassed ? "Success" : "Failure"));
            }
        }
 internal AddTaskEvent(SimpleTaskScheduler scheduler, Task taskToBeAdded)
 {
     this.scheduler     = scheduler;
     this.taskToBeAdded = taskToBeAdded;
 }