如何修改LazyConcurrentDictionary代码实现过期Token自动刷新
实现带自动过期刷新的Token管理LazyConcurrentDictionary
原有代码
LazyConcurrentDictionary 类
public class LazyConcurrentDictionary<TKey, TValue> { private readonly ConcurrentDictionary<TKey, Lazy<TValue>> _concurrentDictionary; public LazyConcurrentDictionary() { _concurrentDictionary = new ConcurrentDictionary<TKey, Lazy<TValue>>(); } public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) { var lazyResult = _concurrentDictionary.GetOrAdd(key, k => new Lazy<TValue>(() => valueFactory(k), LazyThreadSafetyMode.ExecutionAndPublication)); return lazyResult.Value; } }
原有Token使用代码
var dictionary = new LazyConcurrentDictionary<string, Lazy<Tuple<string, DateTime>>>(); var result = dictionary.GetOrAdd("80", k => new Lazy<Tuple<string, DateTime>>(() => { return new Tuple<string, DateTime>(Guid.NewGuid().ToString(), DateTime.Now); }));
解决方案
要实现Token过期自动刷新,核心是在获取Token时检查当前存储的Token是否已过期,如果过期则移除旧条目并重新生成新Token。以下是推荐的实现方式:
方式一:扩展LazyConcurrentDictionary,添加带过期检查的通用方法
直接在原有类中新增支持过期验证的方法,兼顾通用性和线程安全性:
public class LazyConcurrentDictionary<TKey, TValue> { private readonly ConcurrentDictionary<TKey, Lazy<TValue>> _concurrentDictionary; public LazyConcurrentDictionary() { _concurrentDictionary = new ConcurrentDictionary<TKey, Lazy<TValue>>(); } public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) { var lazyResult = _concurrentDictionary.GetOrAdd(key, k => new Lazy<TValue>(() => valueFactory(k), LazyThreadSafetyMode.ExecutionAndPublication)); return lazyResult.Value; } // 新增带过期检查的方法,通过委托传入过期验证逻辑 public TValue GetOrAddWithExpiration(TKey key, Func<TKey, TValue> valueFactory, Func<TValue, bool> isExpired) { // 尝试获取现有值并检查过期状态 if (_concurrentDictionary.TryGetValue(key, out var existingLazy)) { var existingValue = existingLazy.Value; if (!isExpired(existingValue)) { return existingValue; } // 已过期则线程安全地移除旧条目 _concurrentDictionary.TryRemove(key, out _); } // 移除成功或条目不存在,重新生成并添加新值 return GetOrAdd(key, valueFactory); } }
修改Token使用代码
简化泛型嵌套(无需额外嵌套Lazy),传入2小时过期的验证逻辑:
var tokenDictionary = new LazyConcurrentDictionary<string, Tuple<string, DateTime>>(); // 获取或自动刷新Token:当前时间与生成时间差超过2小时则视为过期 var tokenInfo = tokenDictionary.GetOrAddWithExpiration("80", k => Tuple.Create(Guid.NewGuid().ToString(), DateTime.Now), value => DateTime.Now - value.Item2 > TimeSpan.FromHours(2)); string validToken = tokenInfo.Item1;
关键细节说明
- 使用
TryRemove保证线程安全,避免多线程场景下的条目移除冲突 - 过期验证逻辑通过委托传入,让类适配不同的过期规则(如不同时长、自定义过期判定)
- 移除了不必要的
Lazy嵌套,利用LazyConcurrentDictionary内部的Lazy实现懒加载即可
内容的提问来源于stack exchange,提问作者A.R.SEIF
相关产品推荐
相关产品推荐

