缓存原理,自己写一个缓存类

.net中的MemoryCache是通过内部封装一个静态Dictionary

自己写一个缓存,支持过期时间

来看看内部怎么实现的

public class CustomerCache : ICache
    {

        private static ConcurrentDictionary<string, KeyValuePair<DateTime, object>> _CustomerCacheDictionary = new ConcurrentDictionary<string, KeyValuePair<DateTime, object>>();

        static CustomerCache()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    if (_CustomerCacheDictionary.Count > 0)
                    {
                        List<string> list = new List<string>();
                        foreach (var item in _CustomerCacheDictionary)
                        {
                            KeyValuePair<DateTime, object> keyValuePair = item.Value;
                            if (DateTime.Now > keyValuePair.Key)//过期了
                            {
                                list.Add(item.Key);
                            }
                        }
                        foreach (var key in list)
                        {
                            _CustomerCacheDictionary.TryRemove(key,out var v);
                        }
                    }
                    Thread.Sleep(1000);
                }
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="data"></param>
        /// <param name="cacheTime">默认30分钟  单位分钟</param>
        public void Add(string key, object data, int cacheTime = 30)
        {
            if (_CustomerCacheDictionary.ContainsKey(key))
                throw new Exception("相同的key");
            _CustomerCacheDictionary.TryAdd(key, new KeyValuePair<DateTime, object>(DateTime.Now.AddMinutes(cacheTime), data));
        }

        /// <summary>
        /// 应该先检查,再get
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public T Get<T>(string key)
        {
            return (T)_CustomerCacheDictionary[key].Value;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool Contains(string key)
        {
            if (_CustomerCacheDictionary.ContainsKey(key))
            {
                KeyValuePair<DateTime, object> keyValuePair = _CustomerCacheDictionary[key];
                if (DateTime.Now > keyValuePair.Key)//过期了
                {
                    _CustomerCacheDictionary.TryRemove(key,out var v);
                    return false;
                }
                else
                    return true;
            }
            return false;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="func">真实查询数据源的方法</param>
        /// <returns></returns>
        public T GetT<T>(string key, Func<T> func)
        {
            T t;
            if (!this.Contains(key))
            {
                t = func.Invoke();
                this.Add(key, t);
            }
            else
            {
                t = this.Get<T>(key);
            }
            return t;
        }


        public object this[string key] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public int Count {
            get {
                return _CustomerCacheDictionary.Count;
            }
        }

        public void Remove(string key)
        {
            _CustomerCacheDictionary.TryRemove(key, out var v);
        }

        public void RemoveAll()
        {
            _CustomerCacheDictionary.Clear();
        }
    }
public interface ICache
    {
        /// <summary>
        /// Gets or sets the value associated with the specified key.
        /// </summary>
        /// <typeparam name="T">Type</typeparam>
        /// <param name="key">The key of the value to get.</param>
        /// <returns>The value associated with the specified key.</returns>
        T Get<T>(string key);

        /// <summary>
        /// Adds the specified key and object to the cache.
        /// </summary>
        /// <param name="key">key</param>
        /// <param name="data">Data</param>
        /// <param name="cacheTime">Cache time</param>
        void Add(string key, object data, int cacheTime = 30);

        /// <summary>
        /// Gets a value indicating whether the value associated with the specified key is cached
        /// </summary>
        /// <param name="key">key</param>
        /// <returns>Result</returns>
        bool Contains(string key);

        /// <summary>
        /// Removes the value with the specified key from the cache
        /// </summary>
        /// <param name="key">/key</param>
        void Remove(string key);

        /// <summary>
        /// Clear all cache data
        /// </summary>
        void RemoveAll();

        object this[string key] { get; set; }

        int Count { get; }
    }
posted @ 2019-12-14 15:28  .Neterr  阅读(713)  评论(1编辑  收藏  举报