1. 程式人生 > 實用技巧 >一個簡單的令牌桶

一個簡單的令牌桶

由於需求變化,今天臨時寫了一個“令牌桶”類。他的功能是:存放令牌並管理令牌的過期時間

不多說了直接上程式碼:

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