【6月日新计划30】WPF入门-緩存Cache

193 阅读1分钟

MemoryCache要引入一個包

图片.png

1. Interface

public interface ICache
{
    /// <summary>
    ///     获取缓存项,当没有缓存时,使用factory提供的值
    /// </summary>
    /// <param name="key"></param>
    /// <param name="factory"></param>
    /// <returns></returns>
    object Get(string key, Func<string, object> factory);


    /// <summary>
    ///     获取缓存项,没有缓存时返回默认数据
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    object GetOrDefault(string key);

    /// <summary>
    ///     设置缓存项并设置过期时间
    /// </summary>
    /// <param name="key">key</param>
    /// <param name="value">值</param>
    /// <param name="slidingExpireTime">多久未访问则失效</param>
    /// <param name="absoluteExpireTime">超时失效</param>
    void Set(string key, object value, TimeSpan? slidingExpireTime = null,TimeSpan?absoluteExpireTime=null);

    /// <summary>
    ///     移除缓存项
    /// </summary>
    /// <param name="key"></param>
    void Remove(string key);

    /// <summary>
    ///     清空缓存
    /// </summary>
    void Clear();

}

2. 緩存基類

public abstract class CacheBase : ICache
{

    protected readonly object SyncObj = new object();

    protected CacheBase()
    {
    }

    public virtual object Get(string key, Func<string, object> factory)
    {
        var cacheKey = key;
        var item = this.GetOrDefault(key);
        if (item == null)
        {
            lock (this.SyncObj)// TODO: 为何要锁定
            {
                item = this.GetOrDefault(key);
                if (item != null)
                {
                    return item;
                }

                item = factory(key);
                if (item == null)
                {
                    return null;
                }

                this.Set(cacheKey, item);
            }
        }

        return item;
    }
    
    public abstract object GetOrDefault(string key);
    
    public abstract void Set(string key, object value, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null);
    
    public abstract void Remove(string key);
    
    public abstract void Clear();
    
    public virtual void Dispose()
    {

    }
}

3. Demo

注意修改set的有效時間

public class DemoCache : CacheBase
{
    private MemoryCache _memoryCache;

    public DemoCache()
        : base()
    {
        this._memoryCache = new MemoryCache("DemoCache");
    }
    
    public override object GetOrDefault(string key)
    {
        return this._memoryCache.Get(key);

    }

    public override void Set(string key, object value, TimeSpan? slidingExpireTime = null, TimeSpan? absoluteExpireTime = null)
    {
        if (value == null)
        {
            throw new Exception("Can not insert null values to the cache!");
        }


        var cachePolicy = new CacheItemPolicy();

        if (absoluteExpireTime != null)
        {
            cachePolicy.AbsoluteExpiration = DateTimeOffset.Now.Add(absoluteExpireTime.Value);

        }
        else if (slidingExpireTime != null)
        {
            cachePolicy.SlidingExpiration = slidingExpireTime.Value;
        }
        else
        {
            cachePolicy.AbsoluteExpiration = DateTimeOffset.Now.Add(TimeSpan.FromSeconds(6000));
            

        }

        this._memoryCache.Set(key, value, cachePolicy);

    }

    public override void Remove(string key)
    {
        this._memoryCache.Remove(key);

    }

    public override void Clear()
    {
        // 将原来的释放,并新建一个cache
        this._memoryCache.Dispose();
        this._memoryCache = new MemoryCache("DemoCache");

    }
    
    public override void Dispose()
    {
        this._memoryCache.Dispose();
        base.Dispose();
    }
}

直接在ViewModel中使用


     private readonly DemoCache demoCache;
     
     public DemoViewModel(DemoCache demoCache)
     {
         this.demoCache = demoCache;
     }
     
     public void test(){
         demoCache.Set("A", parameter);
         
         var cust = demoCache.GetOrDefault("A") as string;
         System.Diagnostics.Trace.WriteLine("--- Value : " + cust);
     }