Exemple #1
0
        /// <summary>
        /// 定时添加令牌
        /// </summary>
        private void TokenProcess()
        {
            int sleep = 1000 / MaxQPS;

            if (sleep == 0)
            {
                sleep = 1; //测试过只要不是while(true)且不sleep,就算sleep(1)CPU也没什么开销
            }
            sleep += 1;    //不能卡那么准
            DateTime start = DateTime.Now;

            while (cancellationToken.Token.IsCancellationRequested == false)
            {
                lock (lockObject)
                {
                    var isSuccess = limitedQueue.Enqueue(new object());
                }
                if (DateTime.Now - start < TimeSpan.FromMilliseconds(sleep)) //如果因为等待lock而大于需要的sleep了那就不需要sleep可以直接开始放令牌
                {
                    int newSleep = sleep - (int)(DateTime.Now - start).TotalMilliseconds;
                    if (newSleep >= 0)
                    {
                        Thread.Sleep(newSleep);               //做损失时间补偿(等待造成的时间丢失补偿回来)例如sleep是500ms,等待花费了200ms,那么只需要sleep300ms就够了
                    }
                }
                start = DateTime.Now;
            }
        }
        public bool RequestWithRetry(int retryCount)
        {
            if (retryCount < 0)
            {
                return(false);
            }
            RequestObject requestObject = new RequestObject();
            bool          isInBucket    = false;

            while (retryCount != 0)
            {
                if (limitedQueue.Count < LimitSize && !isInBucket)
                {
                    lock (lockObject)
                    {
                        if (limitedQueue.Count < LimitSize)
                        {
                            limitedQueue.Enqueue(requestObject);
                            isInBucket = true;
                        }
                    }
                }
                if (requestObject.HasHandle)
                {
                    return(true);
                }
                Thread.Sleep(System.Math.Max(0, limitedQueue.Count * 1000 / MaxQPS));
                retryCount--;
            }
            return(false);
        }
Exemple #3
0
        private readonly object lockObject = new object();//用于加锁
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="maxQPS">最大QPS</param>
        /// <param name="limitSize">最大限制同时并发数</param>
        public TokenBucketLimitingService(int maxQPS, int limitSize)
        {
            MaxQPS    = maxQPS;
            LimitSize = limitSize;

            limitedQueue = new LimitedQueue <object>(limitSize);
            for (int i = 0; i < limitSize; i++)//先放满令牌
            {
                limitedQueue.Enqueue(new object());
            }
            cancellationToken = new CancellationTokenSource();
            task = Task.Factory.StartNew(new Action(TokenProcess), cancellationToken.Token);
        }