Exemplo n.º 1
0
        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);
            }
        }
Exemplo n.º 2
0
 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);
         }
     }
 }
Exemplo n.º 3
0
        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);
            }
        }