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()); }
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 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 async Task MultipleUnRegistrationsTest() { var tickGenerator = new TickGenerator(10); ISequencerUC sequencer = SequencerUC .Construct() .Register(Steps.Notify, new StrategyOneOnOneUC()) ; Action action = () => { sequencer.Point(SeqPointTypeUC.Notify, Steps.Notify); }; Task t = await tickGenerator.RegisterAsync(action).WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); for (int i = 0; i < 10; i++) { await sequencer.TestPointAsync(Steps.Notify); } t = await tickGenerator.UnRegisterAsync(action).WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); t = await tickGenerator.UnRegisterAsync(action).WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task AwaitAheadOfDataTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(AwaitAheadOfDataEnum.Enqueue2ItemsBegin, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.Enqueue2ItemsA, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.Enqueue2ItemsEnd, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.EnqueuedItemsAsyncBegin, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.EnqueuedItemsAsyncAwaiting, new StrategyOneOnOneUC()) .Register(AwaitAheadOfDataEnum.EnqueuedItemsAsyncEnd, new StrategyOneOnOneUC()) ; const int throttle = 3; IConcurrentQueueNotifier <string> notifier = new ConcurrentQueueNotifier <string>(throttle); sequencer.Run(() => Enque2Items(sequencer, notifier)); sequencer.Run(() => AwaitAhedOfData(sequencer, notifier)); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.EnqueuedItemsAsyncBegin); IProductionPointUC point = await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.EnqueuedItemsAsyncAwaiting); Task t = point.ProductionArg as Task; Assert.IsFalse(t?.IsCompleted); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.Enqueue2ItemsBegin); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.Enqueue2ItemsA); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.EnqueuedItemsAsyncEnd); await sequencer.TestPointCompleteAsync(AwaitAheadOfDataEnum.Enqueue2ItemsEnd); Assert.AreEqual(1, notifier.Count()); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task EnslaveAndDelayMessangerTest() { //The danger is hidden in using the messangers thread to run continuation, //for semaphores in messanger/receiver blocks it can easily create deadlock, //For monitor lock in messanger/receiver blocks it should mostly work well, // recursivness takes care of it. //For UI it is highly dangerous and unpredictable! //If messanger is executed from UI, it will most often execute continuation synchronously on UI. //BUT! //In certain cases TaskCompletionSource can decide to run continuation asynchronously on UI. //Same as if a delegate would not be executed directly but through BeginInvoke scheduled to queue //and executed later. //It is a breaking change to subsequent code, that might expect something will be already done before //subsequent code is executed. TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(); 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 its own thread await sequencer.TestPointAsync(TCS.ReceiverInitialize); //receiver was running and is now awaiting tcs.Task sequencer.Run(seq => Messanger(seq, tcs)); //run Messanger in its own thread await sequencer.TestPointAsync(TCS.MessangerSetResult); //messanger SetResult executed var worker = await sequencer.TestPointAsync(TCS.ReceiverRecord); //receiver was running and is now awaiting tcs.Task //Messanger was executing code inside Receiver synchronously! Assert.AreEqual(worker.ProductionArg, nameof(Messanger)); await sequencer.WhenAll(); // wait for all tasks to complete Assert.DoesNotThrow(() => sequencer.TryReThrowException()); }
public async Task DisposeBasicTest() { var tickGenerator = new TickGenerator(10); ISequencerUC sequencer = SequencerUC .Construct() .Register(Steps.Notify, new StrategyOneOnOneUC()) ; Action action = () => { sequencer.Point(SeqPointTypeUC.Notify, Steps.Notify); }; tickGenerator.Dispose(); Task t = await tickGenerator.Disposed.WrapIntoTask(); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); Assert.ThrowsAsync <ObjectDisposedException>(async() => t = await tickGenerator.RegisterAsync(action).WrapIntoTask()); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); Assert.ThrowsAsync <ObjectDisposedException>(async() => t = await tickGenerator.UnRegisterAsync(action).WrapIntoTask()); Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task Concurrent2RegisterResultTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(TimerProcessorSequencer.RegisterStatus, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.RegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.UnRegisterStatus, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.UnRegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.Processing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.ExclusiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.BeginActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.EndActiveProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.ActionsProcessing, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.ActionsProcessingCount, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.TryUpdateTimerBegin, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.TryUpdateTimerEnd, new StrategyOneOnOneUC()) .Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TimerProcessorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) ; var timeprocessor = new TimerProcessor(10, new RealTimeSource(), sequencer); var tt = Task.Run(() => timeprocessor.RegisterResultAsync(TimeSpan.FromMilliseconds(10000), new object()).WrapIntoTask()); var rStatus = await sequencer.TestPointAsync(TimerProcessorSequencer.RegisterStatus); Assert.AreEqual(TimerProcessorStatus.Operating, rStatus.ProductionArg); var rActiveProcesing = await sequencer.TestPointAsync(TimerProcessorSequencer.RegisterActiveProcessing); Assert.AreEqual(false, rActiveProcesing.ProductionArg); var processing = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); var processingResult = (TimerProcessor.ProcessingResult)processing.ProductionArg; Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingResult); var exclusiveProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); exclusiveProcessing.Complete(); var beginActiveProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); beginActiveProcessing.Complete(); var actionProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessing); actionProcessing.Complete(); Assert.AreEqual(false, actionProcessing.ProductionArg); var updateTimerBegin = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerBegin); updateTimerBegin.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.None, updateTimerBegin.ProductionArg); var updateTimerEnd = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerEnd); updateTimerEnd.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.Activate | TimerProcessorTimerStatus.IsActive | TimerProcessorTimerStatus.Changed, updateTimerEnd.ProductionArg); var endActiveProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.EndActiveProcessing); endActiveProcessing.Complete(); Assert.AreEqual(TimerProcessorStatus.Operating, endActiveProcessing.ProductionArg); Task <TaskCompletionSource <object> > t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); TaskCompletionSource <object> tcs = t.Result; for (int i = 0; i < 10; i++) { var callBackProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.CallBackProcessing); callBackProcessing.Complete(); var processingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); var processingCycleResult = (TimerProcessor.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); var actionProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(true, actionProcessingCycle.ProductionArg); var actionProcessingCountCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessingCount); Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); //for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) //{ // await sequencer.TestPointAsync(Steps.Notify); //} var updateTimerBeginCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.Activate | TimerProcessorTimerStatus.IsActive, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TimerProcessorStatus.Operating, endActiveProcessingCycle.ProductionArg); } for (int i = 0; i < 1; i++) { //var callBackProcessing = await sequencer.TestPointAsync(TimerProcessorSequencer.CallBackProcessing); //callBackProcessing.Complete(); //var processingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); //var processingCycleResult = (TimerProcessor.ProcessingResult)processingCycle.ProductionArg; //Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingCycleResult); //var exclusiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); //exclusiveProcessingCycle.Complete(); //var beginActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); //beginActiveProcessingCycle.Complete(); //ActiveProcessing tt = Task.Run(() => timeprocessor.UnRegisterAsync(tcs).WrapIntoTask()); var rStatusCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.UnRegisterStatus); Assert.AreEqual(TimerProcessorStatus.Operating, rStatusCycle.ProductionArg); var rActiveProcesingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.UnRegisterActiveProcessing); Assert.AreEqual(false, rActiveProcesingCycle.ProductionArg); var processingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.Processing); var processingCycleResult = (TimerProcessor.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TimerProcessor.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); var actionProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(false, actionProcessingCycle.ProductionArg); //var actionProcessingCountCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.ActionsProcessingCount); //Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); //for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) //{ // await sequencer.TestPointAsync(Steps.Notify); //} var updateTimerBeginCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TimerProcessorTimerStatus.Changed, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TimerProcessorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TimerProcessorStatus.Operating, endActiveProcessingCycle.ProductionArg); } t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task ConcurrentSequencing() { StepConcurrentSequencing = 0; ISequencerUC sequencer = SequencerUC .Construct() .Register(ConcurrentSequencingPhase.Begin, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.EnteringSimpleLock, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.Locked, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.LockedNotify, new StrategyOneOnOneUC()) .Register(ConcurrentSequencingPhase.End, new StrategyOneOnOneUC()) ; //StrategyOneOnOneUC each production code point(per thread) is matched to unit test point //that is per point and per thread in production code IAsyncLockUC Lock = new AsyncSpinLockUC(); //start first worker sequencer.Run(seq => ConcurrentSequencingWorker(Lock, sequencer)); //await first worker to get to Begin point var Begin1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Begin); //first worker at Begin point //start second worker sequencer.Run(seq => ConcurrentSequencingWorker(Lock, sequencer)); //await second worker to get to Begin point var Begin2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Begin); //second worker at Begin point //allow first worker to continue to Locked point Begin1.Complete(); //Begin1.Fail(new Exception("Hmmmm")); var notify1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.EnteringSimpleLock); //await first worker to get to Locked point var Locked1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Locked); Assert.AreEqual(0, Locked1.ProductionArg); //first worker at Locked point //spinlock is locked, first worker has exclusive access //allow first worker to continue to Locked point it will spin until lock get opened Begin2.Complete(); //this helps us to ensure we do not need thread waiting, //notification are in production code completed awaiters, //immediatelly executiong what is next after the await on notification, //so it is known to be actively running thread! var notify2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.EnteringSimpleLock); //second worker has entered spinlock as is spinning! //let first worker leave spin lock Locked1.Complete(); //first thread is leaving the spinlock, but before leaving step value will be recorderd //second thread is spinning to get inside //LockedNotify can be checked if the recorded step value was 1 => thread 1 inside, thread 2 attempting to get inside var LockedNotify1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.LockedNotify); Assert.AreEqual(1, LockedNotify1.ProductionArg); //this is checking concurrency correctness, as threads were highly probably active during checking //await first worker at End point var End1 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.End); //first worker released spinlock End1.Complete(); //first worker done //await second worker at Locked point var Locked2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.Locked); //let second worker to continue to End point Locked2.Complete(); var LockedNotify2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.LockedNotify); Assert.AreEqual(0, LockedNotify2.ProductionArg); //await second worker at the End point var End2 = await sequencer.TestPointAsync(ConcurrentSequencingPhase.End); //second worker released spinlock End2.Complete(); //second worker done await sequencer.WhenAll(); sequencer.TryReThrowException(); }
public async Task ConcurrentTest() { ISequencerUC sequencer = SequencerUC .Construct() .Register(Steps.Notify, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.RegisterStatus, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.RegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.UnRegisterStatus, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.UnRegisterActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.Processing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.ExclusiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.BeginActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.EndActiveProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.ActionsProcessing, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.ActionsProcessingCount, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.TryUpdateTimerBegin, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.TryUpdateTimerEnd, new StrategyOneOnOneUC()) .Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) //.Register(TickGeneratorSequencer.CallBackProcessing, new StrategyOneOnOneUC()) ; var tickGenerator = new TickGenerator(10, sequencer); Action action = () => { sequencer.Point(SeqPointTypeUC.Notify, Steps.Notify); }; Task <Task> tt = Task.Run(() => tickGenerator.RegisterAsync(action).WrapIntoTask()); var rStatus = await sequencer.TestPointAsync(TickGeneratorSequencer.RegisterStatus); Assert.AreEqual(TickGeneratorStatus.Operating, rStatus.ProductionArg); var rActiveProcesing = await sequencer.TestPointAsync(TickGeneratorSequencer.RegisterActiveProcessing); Assert.AreEqual(false, rActiveProcesing.ProductionArg); var processing = await sequencer.TestPointAsync(TickGeneratorSequencer.Processing); var processingResult = (TickGenerator.ProcessingResult)processing.ProductionArg; Assert.AreEqual(TickGenerator.ProcessingResult.Processed, processingResult); var exclusiveProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.ExclusiveProcessing); exclusiveProcessing.Complete(); var beginActiveProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.BeginActiveProcessing); beginActiveProcessing.Complete(); var actionProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessing); actionProcessing.Complete(); Assert.AreEqual(false, actionProcessing.ProductionArg); var updateTimerBegin = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerBegin); updateTimerBegin.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.None, updateTimerBegin.ProductionArg); var updateTimerEnd = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerEnd); updateTimerEnd.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.Activate | TickGeneratorTimerStatus.IsActive | TickGeneratorTimerStatus.Changed, updateTimerEnd.ProductionArg); var endActiveProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.EndActiveProcessing); endActiveProcessing.Complete(); Assert.AreEqual(TickGeneratorStatus.Operating, endActiveProcessing.ProductionArg); Task t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); for (int i = 0; i < 10; i++) { var callBackProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.CallBackProcessing); callBackProcessing.Complete(); var processingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.Processing); var processingCycleResult = (TickGenerator.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TickGenerator.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); var actionProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(true, actionProcessingCycle.ProductionArg); var actionProcessingCountCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessingCount); Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) { await sequencer.TestPointAsync(Steps.Notify); } var updateTimerBeginCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.Activate | TickGeneratorTimerStatus.IsActive, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TickGeneratorStatus.Operating, endActiveProcessingCycle.ProductionArg); } for (int i = 0; i < 1; i++) { var callBackProcessing = await sequencer.TestPointAsync(TickGeneratorSequencer.CallBackProcessing); callBackProcessing.Complete(); var processingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.Processing); var processingCycleResult = (TickGenerator.ProcessingResult)processingCycle.ProductionArg; Assert.AreEqual(TickGenerator.ProcessingResult.Processed, processingCycleResult); var exclusiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ExclusiveProcessing); exclusiveProcessingCycle.Complete(); var beginActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.BeginActiveProcessing); beginActiveProcessingCycle.Complete(); //ActiveProcessing tt = Task.Run(() => tickGenerator.UnRegisterAsync(action).WrapIntoTask()); var rStatusCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.UnRegisterStatus); Assert.AreEqual(TickGeneratorStatus.Operating, rStatusCycle.ProductionArg); var rActiveProcesingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.UnRegisterActiveProcessing); Assert.AreEqual(true, rActiveProcesingCycle.ProductionArg); var actionProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessing); actionProcessingCycle.Complete(); Assert.AreEqual(true, actionProcessingCycle.ProductionArg); var actionProcessingCountCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.ActionsProcessingCount); Assert.AreEqual(1, actionProcessingCountCycle.ProductionArg); for (int j = 0; j < (int)actionProcessingCountCycle.ProductionArg; j++) { await sequencer.TestPointAsync(Steps.Notify); } var updateTimerBeginCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerBegin); updateTimerBeginCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.IsActive, updateTimerBeginCycle.ProductionArg); var updateTimerEndCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.TryUpdateTimerEnd); updateTimerEndCycle.Complete(); Assert.AreEqual(TickGeneratorTimerStatus.Changed, updateTimerEndCycle.ProductionArg); var endActiveProcessingCycle = await sequencer.TestPointAsync(TickGeneratorSequencer.EndActiveProcessing); endActiveProcessingCycle.Complete(); Assert.AreEqual(TickGeneratorStatus.Operating, endActiveProcessingCycle.ProductionArg); } t = await tt; Assert.IsTrue(t.IsCompleted); Assert.IsFalse(t.IsCanceled); Assert.IsFalse(t.IsFaulted); await sequencer.WhenAll(); sequencer.TryReThrowException(); }