Beispiel #1
0
 public static void Processing(TimerProcessorStatus status, Queue <TimerProcessorCallBackRequest> queue, IOrderedExpiryItems expiryItems)
 {
     while (queue.Count > 0)
     {
         TimerProcessorCallBackRequest request = queue.Dequeue();
         if (request.Request == TimerProcessorRequest.Add)
         {
             request.ProcessingAdd(status, expiryItems);
         }
         else if (request.Request == TimerProcessorRequest.Remove)
         {
             request.ProcessingRemove(status, expiryItems);
         }
     }
 }
        public AsyncTimerProcessorResult <TArg> RegisterAsync <TArg>(TimeSpan delay)
        {
            TimerProcessorCallBackRequest request = TimerProcessorCallBackRequest.Add <TArg>(RealTimeSource.GetUtcNow(), delay);

            if (Status == TimerProcessorStatus.Disposed)
            {
                return(request.TrySetDisposed().GetAsyncResult <TArg>());
            }
            if (Status == TimerProcessorStatus.Disposing)
            {
                return(request.TrySetCanceled().GetAsyncResult <TArg>());
            }

            using (Lock.Enter())
            {
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.RegisterStatus, Status);
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.RegisterActiveProcessing, ActiveProcessing);
                if (Status == TimerProcessorStatus.Disposed)
                {
                    return(request.TrySetDisposed().GetAsyncResult <TArg>());
                }
                if (Status == TimerProcessorStatus.Disposing)
                {
                    return(request.TrySetCanceled().GetAsyncResult <TArg>());
                }
                Requests.Enqueue(request);
                if (ActiveProcessing)
                {
                    return(request.GetAsyncResult <TArg>());
                }
            }

            if (Processing(processActions: false) == ProcessingResult.Processed)
            {
                return(request.GetAsyncResult <TArg>());
            }

            using (Lock.Enter())
            {
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.RegisterEnd, Status);
                if (Status == TimerProcessorStatus.Disposed)
                {
                    return(request.TrySetDisposed().GetAsyncResult <TArg>());
                }
                TryUpdateTimer(activate: true);
                return(request.GetAsyncResult <TArg>());
            }
        }
        public AsyncTimerProcessorResult <TArg> UnRegisterAsync <TArg>(TaskCompletionSource <TArg> tcs)
        {
            if (tcs == null)
            {
                throw new ArgumentNullException(nameof(tcs));
            }
            TimerProcessorCallBackRequest request = TimerProcessorCallBackRequest.Remove(tcs);

            if (Status == TimerProcessorStatus.Disposed)
            {
                return(request.TrySetDisposed().GetAsyncResult <TArg>());
            }

            using (Lock.Enter())
            {
                if (Status == TimerProcessorStatus.Disposed)
                {
                    return(request.TrySetDisposed().GetAsyncResult <TArg>());
                }
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.UnRegisterStatus, Status);
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.UnRegisterActiveProcessing, ActiveProcessing);
                Requests.Enqueue(request);
                if (ActiveProcessing)
                {
                    return(request.GetAsyncResult <TArg>());
                }
            }

            if (Processing(processActions: false) == ProcessingResult.Processed)
            {
                return(request.GetAsyncResult <TArg>());
            }

            using (Lock.Enter())
            {
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.UnRegisterEnd, Status);
                if (Status == TimerProcessorStatus.Disposed)
                {
                    return(request.TrySetDisposed().GetAsyncResult <TArg>());
                }
                TryUpdateTimer(activate: true);
                return(request.GetAsyncResult <TArg>());
            }
        }
        protected virtual void ExclusiveProcessing(bool processActions)
        {
            NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TimerProcessorSequencer.ExclusiveProcessing, processActions);
            TimerProcessorStatus lastStatus;

            using (Lock.Enter())
            {
                ActiveProcessing = true;
                NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TimerProcessorSequencer.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;
                    }
                }

                TimerProcessorCallBackRequest.Processing(lastStatus, WorkingRequests, ExpiryItems);
            }

            bool processing = processActions && lastStatus != TimerProcessorStatus.Disposed && ExpiryItems.Any();

            NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TimerProcessorSequencer.ActionsProcessing, processing);

            if (processing)
            {
                NullSafeSequencer.PointArg(SeqPointTypeUC.Notify, TimerProcessorSequencer.ActionsProcessingCount, ExpiryItems.Count);
                ExpiryItems.TryExpire(RealTimeSource.GetUtcNow());
            }

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

                TimerProcessorCallBackRequest.Processing(lastStatus, WorkingRequests, ExpiryItems);
            }

            using (Lock.Enter())
            {
                ActiveProcessing = false;
                TimerProcessorCallBackRequest.Processing(Status, Requests, ExpiryItems);

                if (Status == TimerProcessorStatus.Operating)
                {
                    bool activate = false;
                    activate |= ExpiryItems.Count > 0;
                    activate |= Requests.Count > 0;
                    TryUpdateTimer(activate);
                }
                else
                {
                    TryUpdateTimer(activate: false);
                    ExpiryItems.CancelAllAndClear();
                    Status = TimerProcessorStatus.Disposed;
                    Ticker.Dispose();
                    DisposedTCS.TrySetResult(null);
                }
                NullSafeSequencer.PointArg(SeqPointTypeUC.Match, TimerProcessorSequencer.EndActiveProcessing, Status);
            }
        }