//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://www.yuque.com/rrqm/touchsocket/index // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace TouchSocket.Core { /// /// 一个简单的内存缓存 /// public class MemoryCache : IEnumerable>, ICache { private readonly ConcurrentDictionary> m_pairs = new ConcurrentDictionary>(); private readonly Timer m_timer; /// /// 一个简单的内存缓存 /// public MemoryCache() { m_timer = new Timer((o) => { List list = new List(); foreach (var item in m_pairs) { if (DateTime.Now - item.Value.UpdateTime > item.Value.Duration) { list.Add(item.Key); } } foreach (var item in list) { OnRemove(item, out _); } }, null, 0, 60 * 1000); } /// /// 当每个元素超时被移除时触发。 /// public Action> Remove { get; set; } /// /// /// /// public bool AddCache(ICacheEntry entity) { return m_pairs.TryAdd(entity.Key, entity); } /// /// /// /// /// public Task AddCacheAsync(ICacheEntry entity) { return EasyTask.Run(() => { return AddCache(entity); }); } /// /// 清空所有缓存 /// public void ClearCache() { m_pairs.Clear(); } /// /// /// /// public Task ClearCacheAsync() { return EasyTask.Run(() => { ClearCache(); }); } /// /// /// /// /// public bool ContainsCache(TKey key) { if (m_pairs.TryGetValue(key, out ICacheEntry cache)) { if (cache.Duration == TimeSpan.Zero) { return true; } else { if (DateTime.Now - cache.UpdateTime > cache.Duration) { OnRemove(key, out _); return false; } else { return true; } } } return false; } /// /// /// /// /// public Task ContainsCacheAsync(TKey key) { return EasyTask.Run(() => { return ContainsCache(key); }); } /// /// 获取缓存实体。 /// /// /// public ICacheEntry GetCache(TKey key) { ICacheEntry cache; if (m_pairs.TryGetValue(key, out cache)) { if (cache.Duration == TimeSpan.Zero) { return cache; } else { if (DateTime.Now - cache.UpdateTime > cache.Duration) { OnRemove(key, out _); return default; } else { return cache; } } } return default; } /// /// /// /// /// public Task> GetCacheAsync(TKey key) { return EasyTask.Run(() => { return GetCache(key); }); } /// /// /// /// public IEnumerator> GetEnumerator() { return m_pairs.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } /// /// 移除缓存 /// /// /// /// public bool RemoveCache(TKey key, out ICacheEntry entity) { return OnRemove(key, out entity); } /// /// 移除缓存 /// /// /// public bool RemoveCache(TKey key) { return OnRemove(key, out _); } /// /// /// /// /// public Task RemoveCacheAsync(TKey key) { return EasyTask.Run(() => { return RemoveCache(key); }); } /// /// /// /// /// public bool SetCache(ICacheEntry entity) { m_pairs.AddOrUpdate(entity.Key, entity, (k, v) => { return entity; }); return true; } /// /// /// /// /// public Task SetCacheAsync(ICacheEntry entity) { return EasyTask.Run(() => { return SetCache(entity); }); } /// /// 获取对应的值。 /// /// /// /// /// public bool TryGetValue(TKey key, out TValue value, bool update = false) { if (m_pairs.TryGetValue(key, out ICacheEntry cache)) { if (cache.Duration == TimeSpan.Zero) { if (update) { cache.UpdateTime = DateTime.Now; } value = cache.Value; return true; } else { if (DateTime.Now - cache.UpdateTime > cache.Duration) { RemoveCache(key); value = default; return false; } else { if (update) { cache.UpdateTime = DateTime.Now; } value = (TValue)cache.Value; return true; } } } value = default; return false; } private bool OnRemove(TKey key, out ICacheEntry cache) { if (m_pairs.TryRemove(key, out cache)) { try { Remove?.Invoke(cache); return true; } catch { } } return false; } } }