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()); }
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); }
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); }
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); }
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); } }
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); }
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); }
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 }
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); }
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); }
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); }