public static async Task AwaitDequeue3(ISequencerUC sequencer, IConcurrentQueueNotifier <string> notifier)
        {
            await sequencer.PointAsync(SeqPointTypeUC.Match, Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncBegin);

            string item;

            await notifier.EnqueuedItemsAsync();

            if (!notifier.TryDequeu(out item))
            {
                throw new Exception("Expected data");
            }
            await sequencer.PointAsync(SeqPointTypeUC.Match, Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem, item);

            await notifier.EnqueuedItemsAsync();

            if (!notifier.TryDequeu(out item))
            {
                throw new Exception("Expected data");
            }
            await sequencer.PointAsync(SeqPointTypeUC.Match, Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem, item);

            await notifier.EnqueuedItemsAsync();

            if (!notifier.TryDequeu(out item))
            {
                throw new Exception("Expected data");
            }
            await sequencer.PointAsync(SeqPointTypeUC.Match, Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem, item);

            await sequencer.PointAsync(SeqPointTypeUC.Match, Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncEnd);
        }
        public static ISequencerUC Throw(this   ISequencerUC sequencer,
                                         Func <bool> condition,
                                         Exception innerException                = null,
                                         string message                          = null,
                                         int skipStackFrames                     = 2,
                                         [CallerMemberName] string callerName    = "",
                                         [CallerFilePath] string callerFileName  = "",
                                         [CallerLineNumber] int callerLineNumber = 0)
        {
            if (!(sequencer is SequencerRegisterUC register) || condition == null || !condition())
            {
                return(sequencer);
            }

            string msg = string.Empty;

            msg += $"[{nameof(ISequencerUC)}.{nameof(Throw)}]";
            msg += $"[msg: {message ?? string.Empty}]";
            msg += $"[MethodName:{callerName}]";
            msg += $"[Line:{callerLineNumber}]";
            msg += $"[FileName:{callerFileName}]";

            Exception ex = innerException != null
                        ? new StackTraceExceptionUC(msg, skipStackFrames, innerException)
                        : new StackTraceExceptionUC(msg, skipStackFrames)
            ;

            register.ExceptionRegister.RegisterException(ex);

            return(sequencer);
        }
        public async Task AwaitAlreadyEnqueuedDataTest()
        {
            ISequencerUC sequencer =
                SequencerUC
                .Construct()
                .Register(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsBegin, new StrategyOneOnOneUC())
                .Register(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsEnd, new StrategyOneOnOneUC())
                .Register(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncBegin, new StrategyOneOnOneUC())
                .Register(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncEnd, new StrategyOneOnOneUC())
            ;

            const int throttle = 3;

            IConcurrentQueueNotifier <string> notifier = new ConcurrentQueueNotifier <string>(throttle);

            sequencer.Run(() => Insert2Items(sequencer, notifier));
            sequencer.Run(() => AwaitEnqueuedData(sequencer, notifier));

            await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsBegin);          //enqueue data

            await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.Enqueue2ItemsEnd);            //enqueue completed

            Assert.AreEqual(2, notifier.Count());

            await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncBegin);          //begin awaiting enqueued data

            await sequencer.TestPointCompleteAsync(AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncEnd);            //enqueued data should be detected

            await sequencer.WhenAll();

            sequencer.TryReThrowException();
        }
        public async Task DoNotEnslaveAndDelayMessangerTest()
        {
            //The main difference, here as it should be used, but did not exist till .Net 4.5
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            ISequencerUC sequencer =
                SequencerUC
                .Construct()
                .Register(TCS.ReceiverInitialize, new StrategyOneOnOneUC())
                .Register(TCS.ReceiverRecord, new StrategyOneOnOneUC())
                .Register(TCS.MessangerSetResult, new StrategyOneOnOneUC())
            ;

            sequencer.Run(seq => Receiver(seq, tcs));                        //run Receiver in own thread
            await sequencer.TestPointAsync(TCS.ReceiverInitialize);          //receiver was running and is awaiting tcs now

            sequencer.Run(seq => Messanger(seq, tcs));                       //run Messanger in own thread
            await sequencer.TestPointAsync(TCS.MessangerSetResult);          //messanger SetResult executed

            var worker = await sequencer.TestPointAsync(TCS.ReceiverRecord); //get info about Receivers thread

            //Messanger was not executing code inside Receiver synchronously!
            Assert.AreNotEqual(worker.ProductionArg, nameof(Messanger));

            await sequencer.WhenAll();            // wait for all tasks to complete

            Assert.DoesNotThrow(() => sequencer.TryReThrowException());
        }
示例#5
0
        PointAsyncArg <TEnum, TArg>(this  ISequencerUC sequencer,
                                    SeqPointTypeUC seqPointTypeUC,
                                    TEnum registration,
                                    Func <bool> condition,
                                    TArg arg,
                                    Action <object> injectContinuation = null)
            where TEnum : struct
        {
            SequencerRegisterUC register = sequencer as SequencerRegisterUC;

            if (register == null || condition == null || !condition())
            {
                return(CompletedAwaiter);
            }

            ISequencerExceptionRegister exceptionRegister = register.ExceptionRegister.TryReThrowException();
            ISequencerTaskRegister      taskRegister      = register.TaskRegister;

            ISequencerPointUC <TEnum> seqPoint = register.TryGet(registration);

            return
                (seqPoint?.ProductionPoint(taskRegister, exceptionRegister, seqPointTypeUC, arg, injectContinuation)
                 ?? CompletedAwaiter
                );
        }
        public async Task Insert3ItemsThrottleTest()
        {
            ISequencerUC sequencer =
                SequencerUC
                .Construct()
                .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_Begin, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_A, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_B, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_C_Throttle, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.Enqueue3Items_End, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncBegin, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem, new StrategyOneOnOneUC())
                .Register(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncEnd, new StrategyOneOnOneUC())
            ;

            const int throttle = 3;

            IConcurrentQueueNotifier <string> notifier = new ConcurrentQueueNotifier <string>(throttle);

            sequencer.Run(() => Insert3ItemsThrottle(sequencer, notifier));
            sequencer.Run(() => AwaitDequeue3(sequencer, notifier));

            IProductionPointUC prodPoint;


            await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_Begin);

            await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_A);

            await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_B);

            prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_C_Throttle);

            Assert.IsFalse((prodPoint?.ProductionArg as Task)?.IsCompleted);
            Assert.AreEqual(3, notifier.Count());

            await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncBegin);

            prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem);

            Assert.AreEqual("A", prodPoint?.ProductionArg as string);

            //throttling should be deactivated, resuming
            await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.Enqueue3Items_End);

            prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem);

            Assert.AreEqual("B", prodPoint?.ProductionArg as string);

            prodPoint = await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncDataItem);

            Assert.AreEqual("C", prodPoint?.ProductionArg as string);

            await sequencer.TestPointCompleteAsync(Insert3ItemsThrottleTestEnum.EnqueuedItemsAsyncEnd);

            await sequencer.WhenAll();

            sequencer.TryReThrowException();
        }
        public static async Task AwaitEnqueuedData(ISequencerUC sequencer, IConcurrentQueueNotifier <string> notifier)
        {
            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncBegin);

            await notifier.EnqueuedItemsAsync();

            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAlreadyEnqueuedDataEnum.EnqueuedItemsAsyncEnd);
        }
 private void Messanger(ISequencerUC sequencer, TaskCompletionSource <object> tcs)
 {
     ThreadStaticWorker = nameof(Messanger);            //thread static to detect Receiver is taking same thread
     sequencer.Point(SeqPointTypeUC.Notify, TCS.MessangerSetResult);
     tcs.SetResult(null);
     //before the thread is returned to thread pool, the thread static field is cleaned,
     ThreadStaticWorker = null;
 }
 public TimerProcessor(int period, IRealTimeSource realTimeSource, ISequencerUC sequencer = null)
 {
     if ((RealTimeSource = realTimeSource) == null)
     {
         throw new ArgumentNullException($"{nameof(realTimeSource)}");
     }
     Ticker = new TickGenerator(period, NullSafeSequencer = sequencer);
 }
 void PointArg <TEnum, TArg>(ISequencerUC sequencer,
                             SeqPointTypeUC seqPointTypeUC,
                             TEnum registration,
                             TArg arg,
                             Action <object> injectContinuation = null)
     where TEnum : struct
 {
     sequencer?.Point(seqPointTypeUC, registration, arg, injectContinuation);
 }
        TestPointFailAsync <TEnum>(this  ISequencerUC sequencer,
                                   TEnum registration,
                                   Exception ex = null)
            where TEnum : struct
        {
            IProductionPointUC prodPoint = await sequencer.TestPointAsync(registration);

            prodPoint?.Fail(ex);
            return(prodPoint);
        }
示例#12
0
        public static async Task Enque2Items(ISequencerUC sequencer, IConcurrentQueueNotifier <string> notifier)
        {
            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAheadOfDataEnum.Enqueue2ItemsBegin);

            await notifier.EnqueueAsync("A");

            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAheadOfDataEnum.Enqueue2ItemsA);

            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAheadOfDataEnum.Enqueue2ItemsEnd);
        }
 void Point <TEnum>(ISequencerUC sequencer,
                    Func <bool> condition,
                    SeqPointTypeUC seqPointTypeUC,
                    TEnum registration,
                    object arg = null,
                    Action <object> injectContinuation = null)
     where TEnum : struct
 {
     sequencer?.Point(seqPointTypeUC, registration, condition, arg, injectContinuation);
 }
示例#14
0
 public static void Throw(ISequencerUC sequencer,
                          Exception innerException = null,
                          string message           = null,
                          int skipStackFrames      = 4,
                          [CallerMemberName] string calllerName   = "",
                          [CallerFilePath] string callerFileName  = "",
                          [CallerLineNumber] int callerLineNumber = 0)
 {
     sequencer?.Throw(innerException, message, skipStackFrames, calllerName, callerFileName, callerLineNumber);
 }
        void PointArg <TEnum, TArg>(this  ISequencerUC sequencer,
                                    SeqPointTypeUC seqPointTypeUC,
                                    TEnum registration,
                                    TArg arg,
                                    Action <object> injectContinuation = null)
            where TEnum : struct
        {
            var rslt = sequencer.PointAsyncArg <TEnum, TArg>(seqPointTypeUC, registration, arg, injectContinuation);

            rslt.GetResult();            //sync waiting unless completed awaiter was provided
        }
        TestPointCompleteAsync <TEnum>(this      ISequencerUC sequencer,
                                       TEnum registration,
                                       object testArg            = null,
                                       SeqContinuationUC context = SeqContinuationUC.OnCapturedContext)
            where TEnum : struct
        {
            IProductionPointUC prodPoint = await sequencer.TestPointAsync(registration);

            prodPoint?.Complete(testArg, context);
            return(prodPoint);
        }
示例#17
0
 private static void ConcurrentSequencingConditionalWorker(ISequencerUC sequencer, ILockUC spinLock)
 {
     ConditionalSequencerUC.Point(sequencer, SeqPointTypeUC.Match, ConcurrentSequencingPhaseConditional.Begin);
     ConditionalSequencerUC.Point(sequencer, SeqPointTypeUC.Notify, ConcurrentSequencingPhaseConditional.EnteringSpinLock, Interlocked.Increment(ref StepConcurrentSequencingConditional));
     using (spinLock.Enter())
     {
         ConditionalSequencerUC.Point(sequencer, SeqPointTypeUC.Match, ConcurrentSequencingPhaseConditional.Locked, Interlocked.Decrement(ref StepConcurrentSequencingConditional));
         ConditionalSequencerUC.Point(sequencer, SeqPointTypeUC.Notify, ConcurrentSequencingPhaseConditional.LockedNotify, Interlocked.Add(ref StepConcurrentSequencingConditional, 0));
     }
     ConditionalSequencerUC.Point(sequencer, SeqPointTypeUC.Match, ConcurrentSequencingPhaseConditional.End);
 }
        public static ISequencerUC TryReThrowException(this ISequencerUC sequencer)
        {
            if (!(sequencer is SequencerRegisterUC register))
            {
                return(sequencer);
            }

            register.ExceptionRegister.TryReThrowException();

            return(sequencer);
        }
 private static void ThrowWorker_ConditionalException(bool detect, ISequencerUC sequencer)
 {
     try
     {
         throw new Exception("Detect raised exception");
     }
     catch (Exception ex)
     {
         sequencer.Throw(() => detect, ex);
     }
 }
示例#20
0
 private static void ConcurrentSequencingWorker(SpinLockUC spinLock, ISequencerUC sequencer)
 {
     sequencer.Point(SeqPointTypeUC.Match, ConcurrentSequencingPhase.Begin);
     sequencer.Point(SeqPointTypeUC.Notify, ConcurrentSequencingPhase.EnteringSpinLock, Interlocked.Increment(ref StepConcurrentSequencing));
     using (spinLock.Enter())
     {
         sequencer.Point(SeqPointTypeUC.Match, ConcurrentSequencingPhase.Locked, Interlocked.Decrement(ref StepConcurrentSequencing));
         sequencer.Point(SeqPointTypeUC.Notify, ConcurrentSequencingPhase.LockedNotify, Interlocked.Add(ref StepConcurrentSequencing, 0));
     }
     sequencer.Point(SeqPointTypeUC.Match, ConcurrentSequencingPhase.End);
 }
示例#21
0
        public static async Task AwaitAhedOfData(ISequencerUC sequencer, IConcurrentQueueNotifier <string> notifier)
        {
            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAheadOfDataEnum.EnqueuedItemsAsyncBegin);

            Task t = notifier.EnqueuedItemsAsync();
            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAheadOfDataEnum.EnqueuedItemsAsyncAwaiting, t);

            await t;

            await sequencer.PointAsync(SeqPointTypeUC.Match, AwaitAheadOfDataEnum.EnqueuedItemsAsyncEnd);
        }
示例#22
0
 private static void ThrowWorker_DetectException(ISequencerUC sequencer)
 {
     try
     {
         throw new Exception("Detect raised exception");
     }
     catch (Exception ex)
     {
         sequencer.Throw(ex);
     }
 }
        void Point <TEnum>(this  ISequencerUC sequencer,
                           SeqPointTypeUC seqPointTypeUC,
                           TEnum registration,
                           Func <bool> condition,
                           object arg = null,
                           Action <object> injectContinuation = null)
            where TEnum : struct
        {
            var rslt = sequencer.PointAsync(seqPointTypeUC, registration, condition, arg, injectContinuation);

            rslt.GetResult();            //sync waiting unless completed awaiter was provided
        }
示例#24
0
        public static ISequencerUC Run(this ISequencerUC sequencer, object obj, Action <ISequencerUC, object> action)
        {
            if (!(sequencer is SequencerRegisterUC register))
            {
                return(sequencer);
            }

            register.ExceptionRegister.TryReThrowException();
            ISequencerTaskRegister taskRegister = register.TaskRegister;

            taskRegister.Run(obj, action);
            return(sequencer);
        }
示例#25
0
        public static ISequencerUC Run <TResult>(this ISequencerUC sequencer, Func <TResult> func)
        {
            if (!(sequencer is SequencerRegisterUC register))
            {
                return(sequencer);
            }

            register.ExceptionRegister.TryReThrowException();
            ISequencerTaskRegister taskRegister = register.TaskRegister;

            taskRegister.Run(func);
            return(sequencer);
        }
        private async Task Receiver(ISequencerUC sequencer, TaskCompletionSource <object> tcs)
        {
            sequencer.Point(SeqPointTypeUC.Notify, TCS.ReceiverInitialize);

            await tcs.Task;

            sequencer.Point(SeqPointTypeUC.Notify, TCS.ReceiverRecord, ThreadStaticWorker);            //saving Worker state

            if (ThreadStaticWorker == nameof(Messanger))
            {
                //$"{nameof(Messanger)} is now working for us synchronously!";
            }
        }
        public static ISequencerUC TryReThrowException(this ISequencerUC sequencer)
        {
            SequencerRegisterUC register = sequencer as SequencerRegisterUC;

            if (register == null)
            {
                return(sequencer);
            }

            register.ExceptionRegister.TryReThrowException();

            return(sequencer);
        }
示例#28
0
        public async Task TestAB()
        {
            //create sequencer
            ISequencerUC sequencer = SequencerUC.Construct();

            //create production code
            ProductionCode worker = new ProductionCode(sequencer);

            //register production code sequencer event spots
            //strategy, one production code event is translated to one unit test code event
            sequencer
            .Register(ProductionCode.SequencingEnumTest.SpotBegin, new StrategyOneOnOneUC())
            .Register(ProductionCode.SequencingEnumTest.SpotEnd, new StrategyOneOnOneUC())
            ;

            //start concurrent tasks
            Task.Run(() => { worker.Worker("A"); });
            Task.Run(() => { worker.Worker("B"); });


            //await two production code events
            IProductionPointUC taskWorkerBegin1 = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotBegin);

            IProductionPointUC taskWorkerBegin2 = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotBegin);

            IProductionPointUC taskWorkerBeginA;
            IProductionPointUC taskWorkerBeginB;

            //detect which event is which
            taskWorkerBeginA = (string)taskWorkerBegin1.ProductionArg == "A" ? taskWorkerBegin1 : null;
            taskWorkerBeginA = (string)taskWorkerBegin2.ProductionArg == "A" ? taskWorkerBegin2 : taskWorkerBeginA;

            //detect which event is which
            taskWorkerBeginB = (string)taskWorkerBegin1.ProductionArg == "B" ? taskWorkerBegin1 : null;
            taskWorkerBeginB = (string)taskWorkerBegin2.ProductionArg == "B" ? taskWorkerBegin2 : taskWorkerBeginB;

            //decide about the order of execution
            taskWorkerBeginA.Complete("A runs first");

            //await A to run to SpotB
            IProductionPointUC taskWorkerEndA = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotEnd);

            //decide about the order of execution
            taskWorkerBeginB.Complete("B runs second");


            IProductionPointUC taskWorkerEndB = await worker.Sequencer.TestPointAsync(ProductionCode.SequencingEnumTest.SpotEnd);

            taskWorkerEndA.Complete("A continue");
            taskWorkerEndB.Complete("B continue");
        }
        private static async Task ConcurrentSequencingWorker(IAsyncLockUC Lock, ISequencerUC sequencer)
        {
            await sequencer.PointAsync(SeqPointTypeUC.Match, ConcurrentSequencingPhase.Begin);

            await sequencer.PointAsync(SeqPointTypeUC.Notify, ConcurrentSequencingPhase.EnteringSimpleLock, Interlocked.Increment(ref StepConcurrentSequencing));

            using (await Lock.Enter())
            {
                await sequencer.PointAsync(SeqPointTypeUC.Match, ConcurrentSequencingPhase.Locked, Interlocked.Decrement(ref StepConcurrentSequencing));

                await sequencer.PointAsync(SeqPointTypeUC.Notify, ConcurrentSequencingPhase.LockedNotify, Interlocked.Add(ref StepConcurrentSequencing, 0));
            }
            await sequencer.PointAsync(SeqPointTypeUC.Match, ConcurrentSequencingPhase.End);
        }
        private static async Task ConcurrentSequencingAsyncWorker(ILockUC spinLock, ISequencerUC sequencer)
        {
            await sequencer.PointAsync(SeqPointTypeUC.Match, ConcurrentSequencingPhaseAsync.Begin);

            await sequencer.PointAsync(SeqPointTypeUC.Notify, ConcurrentSequencingPhaseAsync.EnteringSpinLock, Interlocked.Increment(ref StepConcurrentSequencingAsync));

            using (spinLock.Enter())
            {
                await sequencer.PointAsync(SeqPointTypeUC.Match, ConcurrentSequencingPhaseAsync.Locked, Interlocked.Decrement(ref StepConcurrentSequencingAsync));

                await sequencer.PointAsync(SeqPointTypeUC.Notify, ConcurrentSequencingPhaseAsync.LockedNotify, Interlocked.Add(ref StepConcurrentSequencingAsync, 0));
            }
            await sequencer.PointAsync(SeqPointTypeUC.Match, ConcurrentSequencingPhaseAsync.End);
        }