public Task RegisterAsync(Action asyncCallback) { if (asyncCallback == null) { throw new ArgumentNullException(nameof(asyncCallback)); } CallBackRequest request = new CallBackRequest(asyncCallback, TickGeneratorRequest.Add); if (Status == TickGeneratorStatus.Disposed) { return(request.TrySetDisposed().Task); } if (Status == TickGeneratorStatus.Disposing) { return(request.TrySetCanceled().Task); } using (Lock.Enter()) { NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TickGeneratorSequencer.RegisterStatus, Status); NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TickGeneratorSequencer.RegisterActiveProcessing, ActiveProcessing); if (Status == TickGeneratorStatus.Disposed) { return(request.TrySetDisposed().Task); } if (Status == TickGeneratorStatus.Disposing) { return(request.TrySetCanceled().Task); } Requests.Enqueue(request); if (ActiveProcessing) { return(request.Task); } } if (Processing(processActions: false) == ProcessingResult.Processed) { return(request.Task); } using (Lock.Enter()) { NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TickGeneratorSequencer.RegisterEnd, Status); if (Status == TickGeneratorStatus.Disposed) { return(request.TrySetDisposed().Task); } TryUpdateTimer(activate: true); return(request.Task); } }
public static void Processing(TickGeneratorStatus status, Queue <CallBackRequest> queue, ISet <Action> set) { while (queue.Count > 0) { CallBackRequest request = queue.Dequeue(); if (request.Request == TickGeneratorRequest.Add) { request.ProcessingAdd(status, set); } else if (request.Request == TickGeneratorRequest.Remove) { request.ProcessingRemove(status, set); } } }
protected virtual void ExclusiveProcessing(bool processActions) { NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TickGeneratorSequencer.ExclusiveProcessing, processActions); TickGeneratorStatus lastStatus; using (Lock.Enter()) { ActiveProcessing = true; NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TickGeneratorSequencer.BeginActiveProcessing, Status); } while (true) { using (Lock.Enter()) { lastStatus = Status; while (Requests.Count > 0 && WorkingRequests.Count < MaxActiveRequests) { WorkingRequests.Enqueue(Requests.Dequeue()); } if (Requests.Count <= 0 && WorkingRequests.Count <= 0) { break; } } CallBackRequest.Processing(lastStatus, WorkingRequests, Actions); } bool processing = processActions && lastStatus != TickGeneratorStatus.Disposed && Actions.Count > 0; NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TickGeneratorSequencer.ActionsProcessing, processing); if (processing) { NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TickGeneratorSequencer.ActionsProcessingCount, Actions.Count); foreach (Action action in Actions) { action(); } } while (true) { using (Lock.Enter()) { lastStatus = Status; while (Requests.Count > 0 && WorkingRequests.Count < MaxActiveRequests) { WorkingRequests.Enqueue(Requests.Dequeue()); } if (Requests.Count <= 0 && WorkingRequests.Count <= 0) { break; } } CallBackRequest.Processing(lastStatus, WorkingRequests, Actions); } using (Lock.Enter()) { ActiveProcessing = false; CallBackRequest.Processing(lastStatus, Requests, Actions); if (Status == TickGeneratorStatus.Operating) { bool activate = false; activate |= Actions.Count > 0; activate |= Requests.Count > 0; TryUpdateTimer(activate); } else { TryUpdateTimer(activate: false); Period = null; Actions.Clear(); Status = TickGeneratorStatus.Disposed; DisposedTCS.TrySetResult(null); } NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TickGeneratorSequencer.EndActiveProcessing, Status); } }