Пример #1
0
        public void TestDispatcherScalability()
        {
            using (Reference <ILogger> loggerRef = Reference <ILogger> .Create(new TraceLogger(true)))
            {
                const int InitSeqNum  = 1000000;
                const int scaleFactor = 20; // => 20^4 (or 160,000) tasks

                int        dispatchCount = 0;
                int        callbackCount = 0;
                Dispatcher seq           = new Dispatcher(loggerRef.Target, "TestCount");
                try
                {
                    // setup Dispatcher handles
                    DispatcherHandle   handle0 = seq.GetDispatcherHandle("");
                    DispatcherHandle[] handle1 = new DispatcherHandle[scaleFactor];
                    DispatcherHandle[,] handle2     = new DispatcherHandle[scaleFactor, scaleFactor];
                    DispatcherHandle[, ,] handle3   = new DispatcherHandle[scaleFactor, scaleFactor, scaleFactor];
                    DispatcherHandle[, , ,] handle4 = new DispatcherHandle[scaleFactor, scaleFactor, scaleFactor, scaleFactor];
                    //TestMsg prev_msg0 = null;
                    //TestMsg[] prev_msg1 = new TestMsg[scaleFactor];
                    //TestMsg[,] prev_msg2 = new TestMsg[scaleFactor, scaleFactor];
                    //TestMsg[, ,] prev_msg3 = new TestMsg[scaleFactor, scaleFactor, scaleFactor];
                    for (int a = 0; a < scaleFactor; a++)
                    {
                        string aKey = "a" + a.ToString();
                        handle1[a] = seq.GetDispatcherHandle(aKey);
                        for (int b = 0; b < scaleFactor; b++)
                        {
                            string bKey = aKey + "/" + "b" + a.ToString();
                            handle2[a, b] = seq.GetDispatcherHandle(bKey);
                            for (int c = 0; c < scaleFactor; c++)
                            {
                                string cKey = bKey + "/" + "c" + a.ToString();
                                handle3[a, b, c] = seq.GetDispatcherHandle(cKey);
                                for (int d = 0; d < scaleFactor; d++)
                                {
                                    string dKey = cKey + "/" + "d" + a.ToString();
                                    handle4[a, b, c, d] = seq.GetDispatcherHandle(dKey);
                                }
                            }
                        }
                    }

                    // dispatch some events and check sequence
                    SendOrPostCallback callback = delegate(object state)
                    {
                        Interlocked.Increment(ref callbackCount);
                        TestMsg msg = (TestMsg)state;
                        //loggerRef.Target.LogDebug("{0} SeqNum ({1}) callback commenced.", msg.Title, msg.N);
                        //Thread.Sleep(30 - (msg.L * 10));
                        //loggerRef.Target.LogDebug("{0} SeqNum ({1}) callback completed.", msg.Title, msg.N);
                    };
                    loggerRef.Target.LogDebug("dispatching tasks...");
                    int seqnum = InitSeqNum;
                    handle0.DispatchObject(callback, new TestMsg(seqnum++));
                    for (int a = 0; a < scaleFactor; a++)
                    {
                        handle1[a].DispatchObject(callback, new TestMsg(seqnum++, a));
                        for (int b = 0; b < scaleFactor; b++)
                        {
                            handle2[a, b].DispatchObject(callback, new TestMsg(seqnum++, a, b));
                            for (int c = 0; c < scaleFactor; c++)
                            {
                                handle3[a, b, c].DispatchObject(callback, new TestMsg(seqnum++, a, b, c));
                                for (int d = 0; d < scaleFactor; d++)
                                {
                                    handle4[a, b, c, d].DispatchObject(callback, new TestMsg(seqnum++, a, b, c, d));
                                }
                                handle3[a, b, c].DispatchObject(callback, new TestMsg(seqnum++, a, b, c));
                            }
                            handle2[a, b].DispatchObject(callback, new TestMsg(seqnum++, a, b));
                        }
                        handle1[a].DispatchObject(callback, new TestMsg(seqnum++, a));
                    }
                    handle0.DispatchObject(callback, new TestMsg(seqnum++));
                    dispatchCount = (seqnum - InitSeqNum);
                    loggerRef.Target.LogDebug("dispatched {0} tasks.", dispatchCount);
                }
                finally
                {
                    long n = seq.Wait(TimeSpan.FromSeconds(0));
                    while (n > 0)
                    {
                        loggerRef.Target.LogDebug("waiting for {0} tasks", n);
                        n = seq.Wait(TimeSpan.FromSeconds(5));
                    }
                    seq = null;
                    loggerRef.Target.LogDebug("{0} tasks completed.", callbackCount);
                    // test
                    Assert.AreEqual <int>(dispatchCount, callbackCount);
                }
            }
        }
Пример #2
0
 public void TestDispatcherParallelism()
 {
     using (Reference <ILogger> loggerRef = Reference <ILogger> .Create(new TraceLogger(true)))
     {
         Int32 counter = 10000;
         // dispatches a series of serial and parallel tasks
         Dispatcher seq = new Dispatcher(loggerRef.Target, "UnitTest");
         try
         {
             DispatcherHandle key0_root = seq.GetDispatcherHandle("");
             DispatcherHandle key1_slow = seq.GetDispatcherHandle("slow");
             DispatcherHandle key1_norm = seq.GetDispatcherHandle("norm");
             DispatcherHandle key1_fast = seq.GetDispatcherHandle("fast");
             // start first global task
             key0_root.DispatchObject(delegate(object state)
             {
                 int count1 = Interlocked.Increment(ref counter);
                 loggerRef.Target.LogDebug("[{0}]key0_root: (a) running", count1);
                 Thread.Sleep(1000);
                 int count2 = Interlocked.Increment(ref counter);
                 loggerRef.Target.LogDebug("[{0}]key0_root: (a) stopped", count2);
             }, null);
             Assert.AreEqual <long>(1, seq.Wait(TimeSpan.Zero));
             // start 1 slow (3 second) task
             for (int i = 0; i < 1; i++)
             {
                 key1_slow.DispatchObject(delegate(object state)
                 {
                     string name = (string)state;
                     int count1  = Interlocked.Increment(ref counter);
                     loggerRef.Target.LogDebug("[{1}]key1_slow: ({0}) running", name, count1);
                     Thread.Sleep(3000);                                // 3 secs
                     int count2 = Interlocked.Increment(ref counter);
                     loggerRef.Target.LogDebug("[{1}]key1_slow: ({0}) stopped", name, count2);
                 }, i.ToString());
                 Assert.AreEqual <long>(i + 2, seq.Wait(TimeSpan.Zero));
             }
             // start 3 normal (1 second) tasks
             for (int i = 0; i < 3; i++)
             {
                 key1_norm.DispatchObject(delegate(object state)
                 {
                     string name = (string)state;
                     int count1  = Interlocked.Increment(ref counter);
                     loggerRef.Target.LogDebug("[{1}]key1_norm: ({0}) running", name, count1);
                     Thread.Sleep(1000);                                // 1 sec
                     int count2 = Interlocked.Increment(ref counter);
                     loggerRef.Target.LogDebug("[{1}]key1_norm: ({0}) stopped", name, count2);
                 }, i.ToString());
                 Assert.AreEqual <long>(i + 3, seq.Wait(TimeSpan.Zero));
             }
             // start 10 fast (0.1 second) tasks
             for (int i = 0; i < 10; i++)
             {
                 key1_fast.DispatchObject(delegate(object state)
                 {
                     string name = (string)state;
                     int count1  = Interlocked.Increment(ref counter);
                     loggerRef.Target.LogDebug("[{1}]key1_fast: ({0}) running", name, count1);
                     Thread.Sleep(100);                                // 0.1 sec
                     int count2 = Interlocked.Increment(ref counter);
                     loggerRef.Target.LogDebug("[{1}]key1_fast: ({0}) stopped", name, count2);
                 }, i.ToString());
                 Assert.AreEqual <long>(i + 6, seq.Wait(TimeSpan.Zero));
             }
             // start last global task
             key0_root.DispatchObject(delegate(object state)
             {
                 //int count = Interlocked.Increment(ref counter);
                 //loggerRef.Target.LogDebug("[{0}]key0_root: (b) running", count);
                 Thread.Sleep(1000);
                 int count2 = Interlocked.Increment(ref counter);
                 loggerRef.Target.LogDebug("[{0}]key0_root: (b) stopped", count2);
             }, null);
             Assert.AreEqual <long>(16, seq.Wait(TimeSpan.Zero));
         }
         finally
         {
             loggerRef.Target.LogDebug("all tasks dispatched");
             long n = seq.Wait(TimeSpan.FromSeconds(0));
             while (n > 0)
             {
                 loggerRef.Target.LogDebug("waiting for {0} tasks", n);
                 n = seq.Wait(TimeSpan.FromSeconds(5));
             }
             seq = null;
             loggerRef.Target.LogDebug("all tasks completed");
         }
     }
 }
Пример #3
0
        public void TestDispatcherSequencing()
        {
            using (Reference <ILogger> loggerRef = Reference <ILogger> .Create(new TraceLogger(true)))
            {
                const int InitSeqNum  = 1000000;
                const int scaleFactor = 50;

                long       seqErrors     = 0;
                int        dispatchCount = 0;
                int        callbackCount = 0;
                Dispatcher seq           = new Dispatcher(loggerRef.Target, "TestCount");
                try
                {
                    // setup Dispatcher handles
                    DispatcherHandle   handle0 = seq.GetDispatcherHandle("");
                    DispatcherHandle[] handle1 = new DispatcherHandle[scaleFactor];
                    DispatcherHandle[,] handle2   = new DispatcherHandle[scaleFactor, scaleFactor];
                    DispatcherHandle[, ,] handle3 = new DispatcherHandle[scaleFactor, scaleFactor, scaleFactor];
                    TestMsg   prev_msg0 = null;
                    TestMsg[] prev_msg1 = new TestMsg[scaleFactor];
                    TestMsg[,] prev_msg2   = new TestMsg[scaleFactor, scaleFactor];
                    TestMsg[, ,] prev_msg3 = new TestMsg[scaleFactor, scaleFactor, scaleFactor];
                    loggerRef.Target.LogDebug("building handles...");
                    for (int a = 0; a < scaleFactor; a++)
                    {
                        string aKey = "a" + a.ToString();
                        handle1[a] = seq.GetDispatcherHandle(aKey);
                        for (int b = 0; b < scaleFactor; b++)
                        {
                            string bKey = aKey + "/" + "b" + b.ToString();
                            handle2[a, b] = seq.GetDispatcherHandle(bKey);
                            for (int c = 0; c < scaleFactor; c++)
                            {
                                string cKey = bKey + "/" + "c" + c.ToString();
                                handle3[a, b, c] = seq.GetDispatcherHandle(cKey);
                            }
                        }
                    }

                    // dispatch some events and check sequence
                    TestMsgDelegate testSeqNum = delegate(TestMsg thisMsg, TestMsg prevMsg)
                    {
                        if (prevMsg == null)
                        {
                            return;
                        }
                        if (thisMsg.N > prevMsg.N)
                        {
                            return;
                        }
                        // failed
                        Interlocked.Increment(ref seqErrors);
                        loggerRef.Target.LogError("{0} SeqNum ({1}) is <= PrevMsg {2} SeqNum ({3})",
                                                  thisMsg.Title, thisMsg.N, prevMsg.Title, prevMsg.N);
                    };

                    SendOrPostCallback callback = delegate(object state)
                    {
                        Interlocked.Increment(ref callbackCount);
                        TestMsg msg = (TestMsg)state;
                        //loggerRef.Target.LogDebug("{0} SeqNum ({1}) callback commenced.", msg.Title, msg.N);
                        Thread.Sleep(3 - (msg.L * 1));
                        // test sequence
                        // - seqnum must be greater than parents and all children
                        if (msg.L == 0)
                        {
                            testSeqNum(msg, prev_msg0);
                            for (int a = 0; a < scaleFactor; a++)
                            {
                                testSeqNum(msg, prev_msg1[a]);
                                for (int b = 0; b < scaleFactor; b++)
                                {
                                    testSeqNum(msg, prev_msg2[a, b]);
                                    for (int c = 0; c < scaleFactor; c++)
                                    {
                                        testSeqNum(msg, prev_msg3[a, b, c]);
                                    }
                                }
                            }
                            prev_msg0 = msg;
                        }
                        if (msg.L == 1)
                        {
                            testSeqNum(msg, prev_msg0);
                            testSeqNum(msg, prev_msg1[msg.A]);
                            for (int b = 0; b < scaleFactor; b++)
                            {
                                testSeqNum(msg, prev_msg2[msg.A, b]);
                                for (int c = 0; c < scaleFactor; c++)
                                {
                                    testSeqNum(msg, prev_msg3[msg.A, b, c]);
                                }
                            }
                            prev_msg1[msg.A] = msg;
                        }
                        if (msg.L == 2)
                        {
                            testSeqNum(msg, prev_msg0);
                            testSeqNum(msg, prev_msg1[msg.A]);
                            testSeqNum(msg, prev_msg2[msg.A, msg.B]);
                            for (int c = 0; c < scaleFactor; c++)
                            {
                                testSeqNum(msg, prev_msg3[msg.A, msg.B, c]);
                            }
                            prev_msg2[msg.A, msg.B] = msg;
                        }
                        if (msg.L == 3)
                        {
                            testSeqNum(msg, prev_msg0);
                            testSeqNum(msg, prev_msg1[msg.A]);
                            testSeqNum(msg, prev_msg2[msg.A, msg.B]);
                            testSeqNum(msg, prev_msg3[msg.A, msg.B, msg.C]);
                            prev_msg3[msg.A, msg.B, msg.C] = msg;
                        }
                        //loggerRef.Target.LogDebug("{0} SeqNum ({1}) callback completed.", msg.Title, msg.N);
                    };
                    loggerRef.Target.LogDebug("dispatching tasks...");
                    int seqnum = InitSeqNum;
                    handle0.DispatchObject(callback, new TestMsg(seqnum++));
                    for (int a = 0; a < scaleFactor; a++)
                    {
                        handle1[a].DispatchObject(callback, new TestMsg(seqnum++, a));
                        for (int b = 0; b < scaleFactor; b++)
                        {
                            handle2[a, b].DispatchObject(callback, new TestMsg(seqnum++, a, b));
                            for (int c = 0; c < scaleFactor; c++)
                            {
                                handle3[a, b, c].DispatchObject(callback, new TestMsg(seqnum++, a, b, c));
                            }
                            handle2[a, b].DispatchObject(callback, new TestMsg(seqnum++, a, b));
                        }
                        handle1[a].DispatchObject(callback, new TestMsg(seqnum++, a));
                    }
                    handle0.DispatchObject(callback, new TestMsg(seqnum++));
                    dispatchCount = (seqnum - InitSeqNum);
                    loggerRef.Target.LogDebug("dispatched {0} tasks.", dispatchCount);
                }
                finally
                {
                    long n = seq.Wait(TimeSpan.FromSeconds(0));
                    while (n > 0)
                    {
                        loggerRef.Target.LogDebug("waiting for {0} tasks", n);
                        n = seq.Wait(TimeSpan.FromSeconds(5));
                        Assert.AreEqual <long>(0, Interlocked.Add(ref seqErrors, 0));
                    }
                    seq = null;
                    loggerRef.Target.LogDebug("{0} tasks completed.", callbackCount);
                    // test
                    Assert.AreEqual <int>(dispatchCount, callbackCount);
                    Assert.AreEqual <long>(0, Interlocked.Add(ref seqErrors, 0));
                }
            }
        }