Пример #1
0
        public void PubSubWithDedicatedThreadWithFilter()
        {
            using (var fiber = new ThreadFiber())
            {
                fiber.Start();
                var channel = new Channel <int>();

                var          reset = new AutoResetEvent(false);
                Action <int> onMsg = x =>
                {
                    Assert.IsTrue(x % 2 == 0);
                    if (x == 4)
                    {
                        reset.Set();
                    }
                };
                var sub = new ChannelSubscription <int>(fiber, onMsg);
                sub.FilterOnProducerThread = x => x % 2 == 0;
                channel.SubscribeOnProducerThreads(sub);
                channel.Publish(1);
                channel.Publish(2);
                channel.Publish(3);
                channel.Publish(4);

                Assert.IsTrue(reset.WaitOne(5000, false));
            }
        }
Пример #2
0
        public void Batching()
        {
            using (var fiber = new ThreadFiber())
            {
                fiber.Start();
                var counter = new Channel <int>();
                var reset   = new ManualResetEvent(false);
                var total   = 0;
                Action <IList <int> > cb = delegate(IList <int> batch)
                {
                    total += batch.Count;
                    if (total == 10)
                    {
                        reset.Set();
                    }
                };

                counter.SubscribeToBatch(fiber, cb, 1);

                for (var i = 0; i < 10; i++)
                {
                    counter.Publish(i);
                }

                Assert.IsTrue(reset.WaitOne(10000, false));
            }
        }
Пример #3
0
 public void TestTwoFibers()
 {
     FiberTester.TestPubSubWExtraFiber(ThreadFiber.StartNew(), ThreadFiber.StartNew());
     FiberTester.TestPubSubWExtraFiber(PoolFiber.StartNew(), ThreadFiber.StartNew());
     FiberTester.TestPubSubWExtraFiber(PoolFiber.StartNew(), PoolFiber.StartNew());
     FiberTester.TestPubSubWExtraFiber(PoolFiber.StartNew(), StubFiber.StartNew());
 }
Пример #4
0
        public void BatchingWithKey()
        {
            using (var fiber = new ThreadFiber())
            {
                fiber.Start();
                var counter = new Channel <int>();
                var reset   = new ManualResetEvent(false);
                Action <IDictionary <String, int> > cb = delegate(IDictionary <String, int> batch)
                {
                    if (batch.ContainsKey("9"))
                    {
                        reset.Set();
                    }
                };

                Converter <int, String> keyResolver = x => x.ToString();
                counter.SubscribeToKeyedBatch(fiber, keyResolver, cb, 0);

                for (var i = 0; i < 10; i++)
                {
                    counter.Publish(i);
                }

                Assert.IsTrue(reset.WaitOne(10000, false));
            }
        }
Пример #5
0
        public void MultiConsumer()
        {
            using (var queues = new Disposables())
            {
                IChannel <string> channel = new QueueChannel <string>();

                //Init executing Fibers
                for (int i = 0; i < 5; i++)
                {
                    char OnReceive(string message)
                    {
                        return(message[0]);
                    }

                    IFiber threadFiber = new ThreadFiber(new Executor(), new TimerScheduler(), new SleepingQueue(), i.ToString());
                    threadFiber.Start();
                    queues.Add(threadFiber);
                    channel.Subscribe(threadFiber, x => OnReceive(x));
                }
                Stopwatch sw = new Stopwatch();
                sw.Start();

                //Push messages
                for (int i = 0; i < 1000000; i++)
                {
                    string msg = "[" + i + "] Push";
                    channel.Publish(msg);
                }
                sw.Stop();
                Console.WriteLine("End : " + sw.ElapsedMilliseconds);
            }
        }
Пример #6
0
        public IFiber Build()
        {
            if (_executor == null)
            {
                _executor = new Executor();
            }
            IFiber fiber;

            switch (_type)
            {
            case FiberType.Thread:
                fiber = new ThreadFiber(_executor, new TimerScheduler(), _queue, _name, true, _priority);
                break;

            case FiberType.Pool:
                fiber = new PoolFiber(_executor);
                break;

            case FiberType.Stub:
                fiber = new StubFiber(_executor);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            return(fiber);
        }
        public void DoDemonstration()
        {
            // Two instances of the calculator are created.  One is named "Odd"
            // (it calculates the 1st, 3rd, 5th... values in the sequence) the
            // other is named "Even".  They message each other back and forth
            // with the latest two values and successively build the sequence.
            var limit = 1000;

            // Two channels for communication.  Naming convention is inbound.
            var oddChannel  = new Channel <IntPair>();
            var evenChannel = new Channel <IntPair>();

            using (ThreadFiber oddFiber = new ThreadFiber(), evenFiber = new ThreadFiber())
            {
                oddFiber.Start();

                var oddCalculator = new FibonacciCalculator(oddFiber, "Odd", oddChannel, evenChannel, limit);

                evenFiber.Start();

                new FibonacciCalculator(evenFiber, "Even", evenChannel, oddChannel, limit);

                oddCalculator.Begin(new IntPair(0, 1));

                oddFiber.Join();
                evenFiber.Join();
            }
        }
Пример #8
0
        public void OnlyOneConsumer()
        {
            using (var queues = new Disposables())
            {
                IChannel <int>      channel = new QueueChannel <int>();
                ConcurrentBag <int> results = new ConcurrentBag <int>();

                void OnReceive(int message)
                {
                    results.Add(message);
                }

                //Init executing Fibers
                for (int i = 0; i < 10; i++)
                {
                    IFiber threadFiber = ThreadFiber.StartNew();
                    queues.Add(threadFiber);
                    channel.Subscribe(threadFiber, OnReceive);
                }
                //Push messages
                for (int i = 0; i < 1000000; i++)
                {
                    channel.Publish(i);
                }
                Thread.Sleep(100);
                Assert.AreEqual(1000000, results.Count);
                var r1 = results.OrderBy(x => x).ToArray();
                for (int i = 0; i < 1000000; i++)
                {
                    Assert.AreEqual(i, r1[i]);
                }
            }
        }
Пример #9
0
        public void PointToPointPerfTestWithObject()
        {
            var executor = new BoundedQueue(new PerfExecutor())
            {
                MaxDepth = 100000, MaxEnqueueWaitTimeInMs = 1000
            };

            using (var fiber = new ThreadFiber(executor))
            {
                fiber.Start();
                var             channel = new Channel <object>();
                const int       max     = 5000000;
                var             reset   = new AutoResetEvent(false);
                var             end     = new object();
                Action <object> onMsg   = delegate(object msg)
                {
                    if (msg == end)
                    {
                        reset.Set();
                    }
                };
                channel.Subscribe(fiber, onMsg);
                using (new PerfTimer(max))
                {
                    var msg = new object();
                    for (var i = 0; i <= max; i++)
                    {
                        channel.Publish(msg);
                    }
                    channel.Publish(end);
                    Assert.IsTrue(reset.WaitOne(30000, false));
                }
            }
        }
Пример #10
0
        public void AsyncRequestReplyWithPrivateChannelUsingThreads()
        {
            IFiber responder = new ThreadFiber();

            responder.Start();
            IFiber receiver = new ThreadFiber();

            receiver.Start();

            Channel <Channel <string> > requestChannel = new Channel <Channel <string> >();
            Channel <string>            replyChannel   = new Channel <string>();
            AutoResetEvent             reset           = new AutoResetEvent(false);
            Action <Channel <string> > onRequest       = delegate(Channel <string> reply) { reply.Publish("hello"); };

            requestChannel.Subscribe(responder, onRequest);
            Action <string> onMsg = delegate(string msg)
            {
                Assert.AreEqual("hello", msg);
                reset.Set();
            };

            replyChannel.Subscribe(receiver, onMsg);
            Assert.IsTrue(requestChannel.Publish(replyChannel));
            Assert.IsTrue(reset.WaitOne(10000, false));

            responder.Dispose();
            receiver.Dispose();
        }
Пример #11
0
        private static void RunBoundedQueue()
        {
            var executor = new BoundedQueue(new PerfExecutor())
            {
                MaxDepth = 10000, MaxEnqueueWaitTimeInMs = 1000
            };

            using (var fiber = new ThreadFiber(executor))
            {
                fiber.Start();
                var                channel = new Channel <MsgStruct>();
                const int          max     = 5000000;
                var                reset   = new AutoResetEvent(false);
                Action <MsgStruct> onMsg   = delegate(MsgStruct count)
                {
                    if (count.count == max)
                    {
                        reset.Set();
                    }
                };
                channel.Subscribe(fiber, onMsg);
                using (new PerfTimer(max))
                {
                    for (var i = 0; i <= max; i++)
                    {
                        channel.Publish(new MsgStruct {
                            count = i
                        });
                    }
                    Assert.IsTrue(reset.WaitOne(30000, false));
                }
            }
        }
Пример #12
0
        private static void Execute(Func <ThreadFiber> creator, String name)
        {
            Console.WriteLine(name);
            const int ChannelCount = 5;
            double    msPerTick    = 1000.0 / Stopwatch.Frequency;
            var       channels     = new IChannel <Msg> [ChannelCount];

            for (int i = 0; i < channels.Length; i++)
            {
                channels[i] = new Channel <Msg>();
            }
            var fibers = new ThreadFiber[ChannelCount];

            for (int i = 0; i < fibers.Length; i++)
            {
                fibers[i] = creator();
                fibers[i].Start();
                int            prior  = i - 1;
                bool           isLast = i + 1 == fibers.Length;
                IChannel <Msg> target = !isLast ? channels[i] : null;
                if (prior >= 0)
                {
                    void Cb(Msg message)
                    {
                        if (target != null)
                        {
                            target.Publish(message);
                        }
                        else
                        {
                            long now  = Stopwatch.GetTimestamp();
                            long diff = now - message.Time;
                            if (message.Log)
                            {
                                Console.WriteLine("qTime: " + diff * msPerTick);
                            }
                            message.Latch.Set();
                        }
                    }

                    channels[prior].Subscribe(fibers[i], Cb);
                }
            }
            for (int i = 0; i < 10000; i++)
            {
                var s = new Msg(false);
                channels[0].Publish(s);
                s.Latch.WaitOne();
            }
            for (int i = 0; i < 5; i++)
            {
                var s = new Msg(true);
                channels[0].Publish(s);
                Thread.Sleep(10);
            }
            foreach (ThreadFiber fiber in fibers)
            {
                fiber.Dispose();
            }
        }
Пример #13
0
        public void AsyncStop()
        {
            ThreadFiber threadFiber = new ThreadFiber(new CommandQueue());

            threadFiber.Start();
            threadFiber.Enqueue(threadFiber.Dispose);
            threadFiber.Join();
        }
Пример #14
0
        public void RunThread()
        {
            ThreadFiber threadFiber = new ThreadFiber(new CommandQueue());

            threadFiber.Start();
            threadFiber.Dispose();
            threadFiber.Join();
        }
Пример #15
0
 public void TestBatching()
 {
     FiberTester.TestBatching(ThreadFiber.StartNew());
     FiberTester.TestBatching(PoolFiber.StartNew());
     FiberTester.TestBatching(StubFiber.StartNew());
     FiberTester.TestBatchingWithKey(ThreadFiber.StartNew());
     FiberTester.TestBatchingWithKey(PoolFiber.StartNew());
     FiberTester.TestBatchingWithKey(StubFiber.StartNew());
 }
Пример #16
0
        public void Using_the_load_generator_should_share_the_load()
        {
            Fiber thread1 = new ThreadFiber();

            thread1.Add(() => {
                var generator1 = new LoadGenerator <FirstCommand, FirstResponse>();
                generator1.Run(RemoteBus, LocalBus.Endpoint, Instances.Values.Select(x => x.DataBus), 100, x => new FirstCommand(x));
            });

            thread1.Shutdown(3.Minutes());
        }
Пример #17
0
        public void Should_properly_release_one_waiting_writer()
        {
            const int writerCount  = 10;
            const int messageCount = 1000;

            var complete = new Future <bool>();
            int total    = 0;

            Fiber reader = new ThreadFiber();

            try
            {
                Thread.Sleep(100);

                Stopwatch timer = Stopwatch.StartNew();

                var writers = new List <Fiber>();
                for (int i = 0; i < writerCount; i++)
                {
                    Fiber fiber = new PoolFiber();
                    for (int j = 0; j < messageCount; j++)
                    {
                        fiber.Add(() =>
                        {
                            SuperSleeper.Wait(1);

                            reader.Add(() =>
                            {
                                total++;
                                if (total == writerCount * messageCount)
                                {
                                    complete.Complete(true);
                                }
                            });
                        });
                    }

                    writers.Add(fiber);
                }

                complete.WaitUntilCompleted(20.Seconds()).ShouldBeTrue();

                timer.Stop();

                Trace.WriteLine("Elapsed time: " + timer.ElapsedMilliseconds + "ms (expected " + writerCount * messageCount + ")");
            }
            finally
            {
                reader.Stop();
            }
        }
Пример #18
0
        public void Should_result_in_no_waiting_actions_in_the_queue()
        {
            Fiber fiber = new ThreadFiber();

            fiber.Add(() => Thread.Sleep(1000));

            var called = new Future <bool>();

            fiber.Add(() => called.Complete(true));

            fiber.Shutdown(112.Seconds());

            called.IsCompleted.ShouldBeTrue();
        }
            public FibonacciCalculator(ThreadFiber fiber, string name,
                                       ISubscriber <IntPair> inboundChannel,
                                       IChannel <IntPair> outboundChannel,
                                       int limit)
            {
                _threadFiber     = fiber;
                _name            = name;
                _inboundChannel  = inboundChannel;
                _outboundChannel = outboundChannel;
                _inboundChannel.Subscribe(fiber, CalculateNext);


                _limit = limit;
            }
Пример #20
0
		public void Should_result_in_no_waiting_actions_in_the_queue()
		{
			Fiber fiber = new ThreadFiber();

			fiber.Add(() => Thread.Sleep(1000));

			var called = new Future<bool>();

			fiber.Add(() => called.Complete(true));

			fiber.Shutdown(112.Seconds());

			called.IsCompleted.ShouldBeTrue();
		}
Пример #21
0
        public void PubSubWithDedicatedThread()
        {
            using (var fiber = new ThreadFiber())
            {
                fiber.Start();
                var channel = new Channel <string>();

                var reset = new AutoResetEvent(false);
                channel.Subscribe(fiber, delegate { reset.Set(); });
                channel.Publish("hello");

                Assert.IsTrue(reset.WaitOne(5000, false));
            }
        }
 private static void Execute(Func<ThreadFiber> creator, String name)
 {
     Console.WriteLine(name);
     const int channelCount = 5;
     double msPerTick = 1000.0 / Stopwatch.Frequency;
     var channels = new IChannel<Msg>[channelCount];
     for (int i = 0; i < channels.Length; i++)
         channels[i] = new Channel<Msg>();
     var fibers = new ThreadFiber[channelCount];
     for (int i = 0; i < fibers.Length; i++)
     {
         fibers[i] = creator();
         fibers[i].Start();
         int prior = i - 1;
         bool isLast = i + 1 == fibers.Length;
         IChannel<Msg> target = !isLast ? channels[i] : null;
         if (prior >= 0)
         {
             Action<Msg> cb = delegate(Msg message)
             {
                 if (target != null)
                     target.Publish(message);
                 else
                 {
                     long now = Stopwatch.GetTimestamp();
                     long diff = now - message.Time;
                     if (message.Log)
                         Console.WriteLine("qTime: " + diff * msPerTick);
                     message.Latch.Set();
                 }
             };
             channels[prior].Subscribe(fibers[i], cb);
         }
     }
     for (int i = 0; i < 10000; i++)
     {
         var s = new Msg(false);
         channels[0].Publish(s);
         s.Latch.WaitOne();
     }
     for (int i = 0; i < 5; i++)
     {
         var s = new Msg(true);
         channels[0].Publish(s);
         Thread.Sleep(10);
     }
     foreach (ThreadFiber fiber in fibers)
         fiber.Dispose();
 }
Пример #23
0
        public void Should_properly_release_one_waiting_writer()
        {
            const int writerCount = 10;
            const int messageCount = 1000;

            var complete = new Future<bool>();
            int total = 0;

            Fiber reader = new ThreadFiber();

            try
            {
                Thread.Sleep(100);

                Stopwatch timer = Stopwatch.StartNew();

                var writers = new List<Fiber>();
                for (int i = 0; i < writerCount; i++)
                {
                    Fiber fiber = new ThreadPoolFiber();
                    for (int j = 0; j < messageCount; j++)
                    {
                        fiber.Add(() =>
                            {
                                SuperSleeper.Wait(1);

                                reader.Add(() =>
                                    {
                                        total++;
                                        if (total == writerCount*messageCount)
                                            complete.Complete(true);
                                    });
                            });
                    }

                    writers.Add(fiber);
                }

                complete.WaitUntilCompleted(20.Seconds()).ShouldBeTrue();

                timer.Stop();

                Trace.WriteLine("Elapsed time: " + timer.ElapsedMilliseconds + "ms (expected " + writerCount*messageCount + ")");
            }
            finally
            {
                reader.Stop();
            }
        }
Пример #24
0
        public void MultiConsumerYielding()
        {
            var queues = new List <IFiber>();
            IChannel <string> channel = new QueueChannel <string>();
            int o = 0;

            //Init executing Fibers
            for (int i = 0; i < 5; i++)
            {
                void OnReceive(string message)
                {
                    var firstChar = message[0];

                    if (firstChar == firstChar)
                    {
                        o++;
                    }
                }

                IFiber threadFiber =
                    new ThreadFiber(new Executor(), new TimerScheduler(), new YieldingQueue(), i.ToString());
                threadFiber.Start();
                queues.Add(threadFiber);
                channel.Subscribe(threadFiber, OnReceive);
            }
            Stopwatch sw = new Stopwatch();

            sw.Start();

            //Push messages
            for (int i = 0; i < 1000000; i++)
            {
                string msg = "[" + i + "] Push";
                channel.Publish(msg);
            }
            sw.Stop();
            Console.WriteLine("End : " + sw.ElapsedMilliseconds);
            // Console.ReadLine();

            //#Results:
            //1 ThreadFiber ~= 1sec
            //2 ThreadFiber ~=> 3sec
            //3 ThreadFiber ~=> 5sec
            //4 ThreadFiber ~=> 8sec
            //5 ThreadFiber ~=> 10sec
        }
Пример #25
0
        public void ShouldIncreaseThreadFiberSubscriberCountByOne()
        {
            var fiber = new ThreadFiber();

            fiber.Start();
            var channel = new Channel <int>();

            Assert.AreEqual(0, fiber.NumSubscriptions);
            Assert.AreEqual(0, channel.NumSubscribers);
            channel.Subscribe(fiber, x => { });

            Assert.AreEqual(1, fiber.NumSubscriptions);
            Assert.AreEqual(1, channel.NumSubscribers);
            fiber.Dispose();

            Assert.AreEqual(0, fiber.NumSubscriptions);
            Assert.AreEqual(0, channel.NumSubscribers);
        }
Пример #26
0
        public void MultiConsumer()
        {
            var queues = new List <FiberBase>();
            IChannel <string> channel = new QueueChannel <string>();

            //Init executing Fibers
            for (int i = 0; i < 5; i++)
            {
                Action <string> onReceive = (message) =>
                {
                    var firstChar = message[0];
                };

                FiberBase threadFiber = new ThreadFiber(new Executor(), new TimerScheduler(), new SleepingQueue(), i.ToString());//new DisruptorQueue(1024*1024)
                queues.Add(threadFiber);
                channel.Subscribe(threadFiber, onReceive);
            }


            Stopwatch sw = new Stopwatch();

            sw.Start();

            //Push messages
            for (int i = 0; i < 1000000; i++)
            {
                string msg = "[" + i + "] Push";
                channel.Publish(msg);
            }
            sw.Stop();

            Console.WriteLine("End : " + sw.ElapsedMilliseconds);
            // Console.ReadLine();

            //#Results:
            //1 ThreadFiber ~= 1sec
            //2 ThreadFiber ~=> 3sec
            //3 ThreadFiber ~=> 5sec
            //4 ThreadFiber ~=> 8sec
            //5 ThreadFiber ~=> 10sec
        }
Пример #27
0
        public void MultiConsumer()
        {
            var queues = new List<FiberBase>();
            IChannel<string> channel = new QueueChannel<string>();

            //Init executing Fibers
            for (int i = 0; i < 5; i++)
            {
                Action<string> onReceive = (message) =>
                {
                    var firstChar = message[0];

                };

                FiberBase threadFiber = new ThreadFiber(new Executor(),new TimerScheduler(),new SleepingQueue() , i.ToString());//new DisruptorQueue(1024*1024)
                queues.Add(threadFiber);
                channel.Subscribe(threadFiber, onReceive);
            }

            Stopwatch sw = new Stopwatch();
            sw.Start();

            //Push messages
            for (int i = 0; i < 1000000; i++)
            {
                string msg = "[" + i + "] Push";
                channel.Publish(msg);
            }
            sw.Stop();

            Console.WriteLine("End : " + sw.ElapsedMilliseconds);
               // Console.ReadLine();

            //#Results:
            //1 ThreadFiber ~= 1sec
            //2 ThreadFiber ~=> 3sec
            //3 ThreadFiber ~=> 5sec
            //4 ThreadFiber ~=> 8sec
            //5 ThreadFiber ~=> 10sec
        }
        public void DoDemonstration()
        {
            // We create a source to generate the quadratics.
            var sinkFiber = new ThreadFiber("sink");

            // We create and store a reference to 10 solvers,
            // one for each possible square term being published.
            var quadraticChannels = new IChannel <Quadratic> [10];

            // reference-preservation list to prevent GC'ing of solvers
            var solvers       = new List <QuadraticSolver>();
            var solvedChannel = new Channel <SolvedQuadratic>();

            for (var i = 0; i < quadraticChannels.Length; i++)
            {
                var fiber = new ThreadFiber("solver " + (i + 1));
                fiber.Start();

                quadraticChannels[i] = new Channel <Quadratic>();
                solvers.Add(new QuadraticSolver(fiber, quadraticChannels[i], solvedChannel));
            }


            var source = new QuadraticSource(quadraticChannels, quadraticChannels.Length, DateTime.Now.Millisecond);

            // Finally a sink to output our results.
            sinkFiber.Start();
            new SolvedQuadraticSink(sinkFiber, solvedChannel, quadraticChannels.Length);

            // This starts streaming the equations.
            source.PublishQuadratics();

            // We pause here to allow all the problems to be solved.
            sinkFiber.Join();

            Console.WriteLine("Demonstration complete.");
        }
Пример #29
0
 public void InOrderExecution()
 {
     FiberTester.InOrderExecution(ThreadFiber.StartNew());
     FiberTester.InOrderExecution(PoolFiber.StartNew());
     FiberTester.InOrderExecution(StubFiber.StartNew());
 }
Пример #30
0
 public void TestPubSubSimple()
 {
     FiberTester.TestPubSubSimple(ThreadFiber.StartNew());
     FiberTester.TestPubSubSimple(PoolFiber.StartNew());
     FiberTester.TestPubSubSimple(StubFiber.StartNew());
 }
Пример #31
0
 public void TestPubSubWithFilter()
 {
     FiberTester.TestPubSubWithFilter(ThreadFiber.StartNew());
     FiberTester.TestPubSubWithFilter(PoolFiber.StartNew());
     FiberTester.TestPubSubWithFilter(StubFiber.StartNew());
 }
Пример #32
0
 /// <summary>
 /// Creates a new instance of <see cref="SerialThreadFiber"/> class
 /// </summary>
 public SerialThreadFiber(ThreadPriority threadPriority)
 {
     this.fiber = new ThreadFiber(new DefaultQueue(), "SerialThreadFiber", true, threadPriority);
 }
Пример #33
0
 public void TestReqReply()
 {
     FiberTester.TestReqReply1(ThreadFiber.StartNew());
     FiberTester.TestReqReply1(PoolFiber.StartNew());
     FiberTester.TestReqReply1(StubFiber.StartNew());
 }
Пример #34
0
        private static void Main(string[] args)
        {
            var now = DateTime.Now;

            Log.Info($"Start at {now:HH:mm:ss}");

            /*Nami.Delay(20000).Do(() =>
             * {
             *  foreach (var s in new[] {1, 2, 3})
             *  {
             *      var ss = s;
             *      Nami.Delay(2000).Do(() =>
             *      {
             *          Loop(ss, 0);
             *      });
             *  }
             * });*/
            Nami.Every(450).Milliseconds().Times(2).Do(() => { PrintData("Every 450 Milliseconds", DateTime.Now); });
            Nami.Every(1).Seconds().Times(3).Do(() => { PrintData("Every 1 Seconds Times 3", DateTime.Now); });
            Nami.Every(10).Minutes().Do(() => { PrintData("Every 10 Minutes", DateTime.Now); });
            Nami.Every(10).Minutes().AfterExecuteTask().Do(() =>
            {
                PrintData("Every 10 Minutes and AfterExecuteTask(didn't work)", DateTime.Now);
                Thread.Sleep(4 * 60 * 1000);
            });
            Nami.Every(600).Seconds().AfterExecuteTask().Do(() =>
            {
                PrintData("Every 600 Seconds and sleep 4 Minutes", DateTime.Now);
                Thread.Sleep(4 * 60 * 1000);
            });
            Nami.Delay(4000).Times(4).Do(() => { PrintData("Delay 4000 ms Times 4", DateTime.Now); });

            now = now.AddSeconds(17).AddMilliseconds(100);
            Nami.EveryMonday().At(now.Hour, now.Minute, now.Second).Do(() => { PrintData("Monday", DateTime.Now); });
            Nami.EveryTuesday().At(now.Hour, now.Minute, now.Second).Do(() => { PrintData("Tuesday", DateTime.Now); });
            Nami.EveryWednesday().At(now.Hour, now.Minute, now.Second)
            .Do(() => { PrintData("Wednesday", DateTime.Now); });
            Nami.EveryThursday().At(now.Hour, now.Minute, now.Second)
            .Do(() => { PrintData("Thursday", DateTime.Now); });
            Nami.EveryFriday().At(now.Hour, now.Minute, now.Second).Do(() => { PrintData("Friday", DateTime.Now); });
            Nami.EverySaturday().At(now.Hour, now.Minute, now.Second)
            .Do(() => { PrintData("Saturday", DateTime.Now); });
            Nami.EverySunday().At(now.Hour, now.Minute, now.Second).Do(() => { PrintData("Sunday", DateTime.Now); });

            now = now.AddSeconds(1);
            Nami.Every(1).Hours().At(now.Hour, now.Minute, now.Second).Do(() =>
            {
                PrintData("Every 1 Hours", DateTime.Now);
            });

            now = now.AddSeconds(1);
            Nami.Every(1).Days().At(now.Hour, now.Minute, now.Second)
            .Do(() => { PrintData("Every 1 Days", DateTime.Now); });

            now = now.AddSeconds(1);
            Nami.Everyday().At(now.Hour, now.Minute, now.Second).Do(() => { PrintData("Everyday", DateTime.Now); });

            Console.ReadKey();

            Nami.EverySunday().At(6, 0, 0).Do(() => { PrintData("EverySunday().Days().At(6,0,0)   ", DateTime.Now); });
            Nami.EveryMonday().At(6, 0, 0).Do(() => { PrintData("EveryMonday().Days().At(6,0,0)   ", DateTime.Now); });
            Nami.EveryMonday().At(12, 0, 0).Do(() =>
            {
                PrintData("EveryMonday().Days().At(12,0,0)   ", DateTime.Now);
            });

            Nami.EveryTuesday().At(6, 0, 0).Do(() => { PrintData("EveryMonday().Days().At(6,0,0)   ", DateTime.Now); });
            Nami.EveryTuesday().At(12, 0, 0)
            .Do(() => { PrintData("EveryMonday().Days().At(12,0,0)   ", DateTime.Now); });

            Nami.Everyday().At(6, 0, 0).Do(() => { PrintData("Everyday().At(6,0,0)   ", DateTime.Now); });

            Nami.Every(1).Days().Do(() => { PrintData("Every(1).Days()   ", DateTime.Now); });
            Nami.Every(1).Days().At(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second + 2).Do(() =>
            {
                PrintData("Every(1).Days().At   ", DateTime.Now);
            });
            Nami.Every(2).Days().At(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second + 2).Do(() =>
            {
                PrintData("Every(2).Days().At   ", DateTime.Now);
            });

            Nami.Every(1).Hours().At(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second + 2).Do(() =>
            {
                PrintData("Every Hours   ", DateTime.Now);
            });
            Nami.Every(2).Hours().At(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second + 2).Do(() =>
            {
                PrintData("Every 2 Hours   ", DateTime.Now);
            });
            Nami.Every(1).Minutes().Do(() => { PrintData("Every(1).Minutes()", DateTime.Now); });
            Nami.Every(2).Minutes().Do(() => { PrintData("Every(2).Minutes()", DateTime.Now); });

            Nami.Delay(1).Seconds().Times(5).Do(() =>
            {
                Log.Info($"Nami.Delay(1).Seconds() {DateTime.Now:HH:mm:ss}");
            });
            var d = Nami.Delay(1).Seconds().Times(5).Do(() => { PrintData(" Dispose ", DateTime.Now); });

            d.Dispose();
            Nami.Delay(30).Seconds().Times(5).Do(() => { PrintData("Delay(30) 5 times", DateTime.Now); });
            Nami.RightNow().Times(3).Do(() => { PrintData("RightNow 3 times", DateTime.Now); });
            Nami.RightNow().Do(() => { PrintData("Just RightNow   ", DateTime.Now); });
            Nami.Delay(1000).Milliseconds().Do(() =>
            {
                PrintData($"Just Delay(1000) execute:{DateTime.Now:HH:mm:ss.fff}", DateTime.Now);
            });
            Nami.Every(60000).Milliseconds().Do(() =>
            {
                PrintData("Just Every(60000).Milliseconds()   ", DateTime.Now);
            });
            Nami.Everyday().At(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second + 5)
            .Do(() => { PrintData("Everyday   ", DateTime.Now); });

            Console.ReadKey();
            IFiber pool   = new PoolFiber();
            IFiber thread = new ThreadFiber();

            pool.Start();
            thread.Start();

            pool.ScheduleOnInterval(() => { PrintData("pool  ", DateTime.Now); }, 0, 150000);
            var td = thread.ScheduleOnInterval(() => { PrintData("thread", DateTime.Now); }, 0, 100000);

            thread.ScheduleOnInterval(() => { PrintData("thread ten second", DateTime.Now); }, 0, 100000);
            for (var i = 0; i < 100; i++)
            {
                var i1 = i;
                thread.Enqueue(() => { PrintData($"thread  {i1}", DateTime.Now); });
            }

            pool.Schedule(() =>
            {
                Console.WriteLine($"td Dispose");
                td.Dispose();
                for (var i = 0; i < 10; i++)
                {
                    thread.Enqueue(() => { PrintData("Schedule start thread  ", DateTime.Now); });
                }
            }, 20000);
            Nami.Every(10).Seconds().AfterExecuteTask().Do(() => { RunSleepCron("Af", 10, 600); });
            Nami.Every(10).Seconds().AfterExecuteTask().Do(() => { RunSleepCron("Af", 10, 600); });
            Nami.Every(10).Seconds().BeforeExecuteTask().Do(() => { RunSleepCron("Be", 10, 0); });
            Nami.Every(10).Seconds().BeforeExecuteTask().Do(() => { RunSleepCron("Be", 10, 0); });



            Nami.Every(100).Seconds().Do(() =>
            {
                thread.Enqueue(() => { PrintData(" Nami.Every(1).Seconds().Do  ", DateTime.Now); });
            });

            Nami.Every(150).Seconds().Do(() => { PrintData("Nami  ", DateTime.Now); });
            Nami.Every(1).Hours().At(0, 02, 0).Do(() => { PrintData("Hours  2", DateTime.Now); });
            Nami.Delay(1500).Do(() => { PrintData("Delay  ", DateTime.Now); });
            Nami.EveryTuesday().At(14, 13, 40).Do(() =>
            {
                PrintData("Nami.EveryTuesday().At(n, n, n)  ", DateTime.Now);
            });

            Nami.Every(1).Minutes().Do(() => { PrintData("Nami.Every(1).Minutes()", DateTime.Now); });
            Nami.Every(2).Minutes().At(0, 0, 15).Do(() =>
            {
                PrintData("Nami.Every(2).Minutes().At(0,0,15)", DateTime.Now);
            });

            Nami.Delay(1000).Do(() => { PrintData("Delay  ", DateTime.Now); });
            Nami.Delay(2500).Do(() => { PrintData("Delay  ", DateTime.Now); });
            Nami.Delay(3500).Do(() => { PrintData("Delay  ", DateTime.Now); });
            Nami.Delay(4500).Do(() => { PrintData("Delay  ", DateTime.Now); });
            //thread.Dispose();
            Console.ReadKey();
        }