无论是前端或者是后端,Cache(缓存)都是非常重要的。一个APP中总有10%~20%的数据是你经常需要去请求的。那么这个时候把这些数据cache,是一种明智的选择。(当然,本篇不讲分布式缓存。)这样有2个好处 : 不必频繁请求数据 ,加重服务器的负担 ; 少了网络请求 , I/O操作 , 直接从内存当中读取数据 , 速度是贼拉拉得快。当然,Cache是不能乱用的,不注意使用的话,很可能得到得是脏数据。所以,最好是给数据整个失效的时间 , 这是一个方法 , 另外 ,让Socket主推数据更新也是一个方法。当然了二者可以综合使用。


在C#当中 , 框架提供的 MemoryCache 类是一个相关缓存的类。本篇依据此类做一个关于缓存的Demo。

需要添加引用:

C#缓存_缓存

关于缓存接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AinyCatch.com
{
    public interface ICache
    {
        T Get<T>(String key);
        void Add(String key, Object data, Int32 @cacheTime = 30);
        bool Contains(String key);
        void Remove(String key);
        void RemoveAll();
        Object this[String key] { get; set; }
        int Count { get; }
    }
}

实现 : ICache

注意 : cacheTime为过期时间 : 单位分钟

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Caching;

namespace AinyCatch.com
{
    public sealed class MemoryCache : ICache
    {
        public MemoryCache() { }
        protected ObjectCache Cache
        {
            get
            {
                return System.Runtime.Caching.MemoryCache.Default;
            }
        }


        public T Get<T>(string key)
        {
            if(Cache.Contains(key))
            {
                return (T)Cache[key];
            }
            else
            {
                return default(T);
            }
        }

        public Object Get(string key)
        {
            return Cache[key];
        }

        public void Add(string key, object data, int cacheTime = 30)
        {
            if (data == null) return;
            CacheItemPolicy policy = new CacheItemPolicy();
            policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);
            Cache.Add(new CacheItem(key, data), policy);
        }

        public bool Contains(string key)
        {
            return this.Cache.Contains(key);
        }

        public void Remove(string key)
        {
            this.Cache.Remove(key);
        }

        public void RemoveAll()
        {
            foreach(var @item in this.Cache)
            {
                this.Cache.Remove(@item.Key);
            }
        }

        public object this[string key]
        {
            get { return Cache.Get(key); }
            set { this.Add(key, value); }
        }

        public int Count
        {
            get { return (int)(this.Cache.GetCount()); } 
        }
    }
}

管理:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AinyCatch.com
{
    public sealed class CacheManager
    {
        private CacheManager() { }
        private static ICache cache = null;
        static CacheManager()//静态构造函数不予许出现修饰符 : public , private 等
        {
            cache = (ICache)Activator.CreateInstance(typeof(MemoryCache));
        }

        public static T Get<T>( String key , Func<T> acquire , Int32 @cacheTime = 30 )
        {
            if( cache.Contains(key) )
            {
                return GetData<T>(key);
            }
            else
            {
                T result = acquire.Invoke();
                cache.Add(key, result, @cacheTime);
                return result;
            }
        }

        public static Int32 Count
        {
            get { return cache.Count; }
        }
        public static bool Contains(string key)
        {
            return cache.Contains(key);
        }
        public static T GetData<T>(string key)
        {
            return cache.Get<T>(key);
        }
        public static void Add(string key, object value)
        {
            if (Contains(key))
                cache.Remove(key);
            cache.Add(key, value);
        }

        /// <summary>
        /// 添加缓存数据。
        /// 如果另一个相同键值的数据已经存在,原数据项将被删除,新数据项被添加。
        /// </summary>
        /// <param name="key">缓存数据的键值</param>
        /// <param name="value">缓存的数据,可以为null值</param>
        /// <param name="expiratTime">缓存过期时间间隔(单位:分钟)</param>
        public static void Add(string key, object value, int @expiratTime = 600)
        {
            if (Contains(key))
                cache.Remove(key);
            cache.Add(key, value, @expiratTime);
        }

        /// <summary>
        /// 删除缓存数据项
        /// </summary>
        /// <param name="key"></param>
        public static void Remove(string key)
        {
            cache.Remove(key);
        }

        /// <summary>
        /// 删除所有缓存数据项
        /// </summary>
        public static void RemoveAll()
        {
            cache.RemoveAll();
        }
    }
}

测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AinyCatch.com;

namespace AinyCatch
{
    class Program
    {
        static void Main(string[] args)
        {
            Student student = CacheManager.Get<Student>("Aonaufly", () => new Student() { Id = 11, Name = "Aonaufly" });

            CacheManager.Add("Aonaufly", new Student() { Id = 11, Name = "Aonauflyx" });

            Student studentx = CacheManager.Get<Student>("Aonaufly", () => new Student() { Id = 11, Name = "Aonauflymx" });

            CacheManager.Add("Aonaufly", new Student() { Id = 11, Name = "AonauflyxXXX" }, 12);

            Student studentxx = CacheManager.Get<Student>("Aonaufly", () => new Student() { Id = 11, Name = "Aonauflymxx" });

            Student student1 = CacheManager.Get<Student>("Aonaufly", () => new Student() { Id = 11, Name = "Aonauflyx" });

            Console.Read();
        }
    }

    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
}