一个简单的令牌桶

由于需求变化,今天临时写了一个“令牌桶”类。他的功能是:存放令牌并管理令牌的过期时间

不多说了直接上代码:

    public class TokenBucket
    {
        /// <summary>
        /// 令牌过期时间
        /// 默认60秒
        /// </summary>
        public int TokenTimeOutTrick { get; set; } = 60000;
        private readonly ConcurrentDictionary<string, CancellationTokenSource> buket = new ConcurrentDictionary<string, CancellationTokenSource>();
        /// <summary>
        /// 添加令牌
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool AddToken(string token)
        {
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            var result = buket.TryAdd(token, tokenSource);
            if (result)
            {
#pragma warning disable CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
                TokenTimeOut(token, tokenSource);
#pragma warning restore CS4014 // 由于此调用不会等待,因此在调用完成前将继续执行当前方法
            }
            return result;
        }
        /// <summary>
        /// 令牌过期
        /// </summary>
        /// <param name="token"></param>
        /// <param name="tokenSource"></param>
        /// <returns></returns>
        private async Task TokenTimeOut(string token, CancellationTokenSource tokenSource)
        {
            CancellationToken cancellationToken = tokenSource.Token;
            await Task.Delay(TokenTimeOutTrick, cancellationToken);
            buket.TryRemove(token, out CancellationTokenSource cts);
            if (cts != null)
                cts.Dispose();
        }
        /// <summary>
        /// 删除令牌
        /// </summary>
        /// <param name="token"></param>
        public void ReomveToken(string token)
        {
            var remove = buket.TryRemove(token, out CancellationTokenSource cts);
            try
            {
                if (remove)
                {
                    cts.Cancel();
                }
            }
            catch { }
            finally
            {
                if (cts != null)
                    cts.Dispose();
            }
        }
        /// <summary>
        /// 令牌是否存在
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        public bool HasToken(string token)
        {
            return buket.ContainsKey(token);
        }
    }
原文地址:https://www.cnblogs.com/lws66/p/13509943.html