天天看点

用匿名函数来更方便的使用缓存

一个数据缓存,一般由数据来源,缓存方案,缓存读取来完成,现在有了匿名函数,可以把获取数据来源变为匿名函数。这样就可以直接声明一个缓存:

protected static CacheManager<Company> companyCache = new CacheManager<Company>(new SmsDatabaseCache<Company>(), (key) =>

             {

                 return SmsDatabase.Instance.Context.Company.Where(c => c.ShortNumber == (string)key).SingleOrDefault();

             });

SmsDatabaseCache是一个缓存方案,还可以使用SimpleCache,TimeoutCache等实现了ICache接口的类,因为我的ICacheManager从ICache继承,所以还可以实现级连缓存哟,例如:

SmsDatebaseCache是一个依SmsDatabase.Instance.Context的缓存方案,在LinqContextDispose时,会进行清空数据操作。

用匿名函数来更方便的使用缓存
用匿名函数来更方便的使用缓存

SmsDatabaseCache

    public class SmsDatabaseCache<TData> : ICache<TData>

    {

        private Dictionary<object, TData> cache = new Dictionary<object, TData>();

        public SmsDatabaseCache()

        {

            SmsDatabase.Instance.PreDisposing += (s, e) =>

                {

                    cache.Clear();

                };

        }

        public TData Get(object key)

            return cache[key];

        public void Set(object key, TData data)

            cache[key] = data;

    }

实现代码如下:

用匿名函数来更方便的使用缓存
用匿名函数来更方便的使用缓存

缓存代码

using System;

using System.Collections.Generic;

using System.Text;

using System.Linq;

namespace Evlon.Utils

{

    public interface ICache<TData>

        TData Get(object key);

        void Set(object key, TData data);

    public interface ICacheManager<TData> : ICache<TData>

        Func<object, TData> SourceGetter { get; }

    public class SimpleCache<TData> : ICache<TData>

        #region ICacheManager<TData> 成员

        #endregion

    public class TimeoutCache<TData> : ICache<TData>

        public TimeSpan Expire {get;set;}

        private DateTime timeLastScan = DateTime.Now;

        private Dictionary<object, KeyValuePair<TData, DateTime>> cache = new Dictionary<object, KeyValuePair<TData, DateTime>>();

        public TimeoutCache()

            Expire = TimeSpan.FromMinutes(5);

        private void TryClearExpireObject()

        { 

            TimeSpan ts = DateTime.Now - timeLastScan;

            if (ts.TotalSeconds > Expire.TotalSeconds / 2)

            {

                timeLastScan = DateTime.Now;

                cache.Where(kv => kv.Value.Value  > DateTime.Now.Subtract(Expire)).ToList().ForEach(kv =>

                    {

                        cache.Remove(kv.Key);

                    });

            }

            TryClearExpireObject();

            if(!cache.ContainsKey(key))

                return default(TData);

            KeyValuePair<TData, DateTime> kv = cache[key];

            if (kv.Value.Add(Expire) < DateTime.Now)

                cache.Remove(key);

            return kv.Key;

            cache[key] = new KeyValuePair<TData, DateTime>(data, DateTime.Now);

    public class CacheManager<TData> : ICacheManager<TData>

        private ICache<TData> cache = null;

        public Func<object, TData> SourceGetter { get; private set; }

        public CacheManager(ICache<TData> cache, Func<object, TData> sourceGetter)

            this.cache = cache;

            this.SourceGetter = sourceGetter;

        #region ICacheGetter<TData> 成员

            TData data = cache.Get(key);

            if (data != null)

                return data;

            data = this.SourceGetter(key);

            cache.Set(key, data);

            return data;

}