.NET 缓存的设计

关于缓存的设计
1、什么情况下用缓存

缓存是提高应用程序性能的最好方法之一。运用缓存可以优化数据查询,避免不必要的网络数据回传,和避免执行不必要的完全相同的数据处理逻辑。在实现缓存的时候我们要确定什么时候装入缓存数据。用异步装入缓存或用批处理方式来避免出现客户端数据延迟。
一般来说在一定时间内请求了相同的业务逻辑而没有变更的话,可以采用缓存来设计。数据请求频繁的的请求不适合采用缓存,如论坛的回复,但是论坛的主题是可以采用缓存设计的。
2、缓存设计的步骤
确定缓存数据结构:即设计中哪些数据用到了缓存,设计这些数据的缓存结构
确定缓存什么数据
确定缓存过期规则和清理
确定如何装入缓存数据
3、示例 Community Server的缓存类

 


  1using System;
  2using System.Collections;
  3using System.Text.RegularExpressions;
  4using System.Web;
  5using System.Web.Caching;
  6
  7namespace Larry.Cache
  8{
  9    /// <summary>
 10    /// 缓存类 Community Server的缓存类
 11    /// </summary>

 12    public class BaseCache
 13    {
 14        /// <summary>
 15        /// CacheDependency 说明
 16        /// 如果您向 Cache 中添加某个具有依赖项的项,当依赖项更改时,
 17        /// 该项将自动从 Cache 中删除。例如,假设您向 Cache 中添加某项,
 18        /// 并使其依赖于文件名数组。当该数组中的某个文件更改时,
 19        /// 与该数组关联的项将从缓存中删除。
 20        /// [C#] 
 21        /// Insert the cache item.
 22        /// CacheDependency dep = new CacheDependency(fileName, dt);
 23        /// cache.Insert("key", "value", dep);
 24        /// </summary>

 25        public static readonly int DayFactor = 17280;
 26        public static readonly int HourFactor = 720;
 27        public static readonly int MinuteFactor = 12;
 28        public static readonly double SecondFactor = 0.2;
 29
 30        private static readonly System.Web.Caching.Cache _cache;
 31
 32        private static int Factor = 1440;
 33
 34        /// <summary>
 35        /// 单件模式
 36        /// </summary>

 37        static BaseCache()
 38        {
 39            HttpContext context = HttpContext.Current;
 40            if (context != null)
 41            {
 42                _cache = context.Cache;
 43            }

 44            else
 45            {
 46                _cache = HttpRuntime.Cache;
 47            }

 48        }

 49
 50        /// <summary>
 51        /// 一次性清除所有缓存
 52        /// </summary>

 53        public static void Clear()
 54        {
 55            IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
 56            ArrayList al = new ArrayList();
 57            while (CacheEnum.MoveNext()) //逐个清除
 58            {
 59                al.Add(CacheEnum.Key);
 60            }

 61
 62            foreach (string key in al)
 63            {
 64                _cache.Remove(key);
 65            }

 66
 67        }

 68
 69
 70
 71        public static void RemoveByPattern(string pattern)
 72        {
 73            IDictionaryEnumerator CacheEnum = _cache.GetEnumerator();
 74            Regex regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled);
 75            while (CacheEnum.MoveNext())
 76            {
 77                if (regex.IsMatch(CacheEnum.Key.ToString()))
 78                    _cache.Remove(CacheEnum.Key.ToString());
 79            }

 80        }

 81
 82        /// <summary>
 83        /// 清除特定的缓存
 84        /// </summary>
 85        /// <param name="key"></param>

 86        public static void Remove(string key)
 87        {
 88            _cache.Remove(key);
 89        }

 90
 91        /// <summary>
 92        /// 缓存OBJECT. 
 93        /// </summary>
 94        /// <param name="key"></param>
 95        /// <param name="obj"></param>

 96        public static void Insert(string key, object obj)
 97        {
 98            Insert(key, obj, null1);
 99        }

100
101        /// <summary>
102        /// 缓存obj 并建立依赖项
103        /// </summary>
104        /// <param name="key"></param>
105        /// <param name="obj"></param>
106        /// <param name="dep"></param>

107        public static void Insert(string key, object obj, CacheDependency dep)
108        {
109            Insert(key, obj, dep, MinuteFactor * 3);
110        }

111
112        /// <summary>
113        /// 按秒缓存对象
114        /// </summary>
115        /// <param name="key"></param>
116        /// <param name="obj"></param>
117        /// <param name="seconds"></param>

118        public static void Insert(string key, object obj, int seconds)
119        {
120            Insert(key, obj, null, seconds);
121        }

122
123        /// <summary>
124        /// 按秒缓存对象 并存储优先级
125        /// </summary>
126        /// <param name="key"></param>
127        /// <param name="obj"></param>
128        /// <param name="seconds"></param>
129        /// <param name="priority"></param>

130        public static void Insert(string key, object obj, int seconds, CacheItemPriority priority)
131        {
132            Insert(key, obj, null, seconds, priority);
133        }

134
135        /// <summary>
136        /// 按秒缓存对象 并建立依赖项
137        /// </summary>
138        /// <param name="key"></param>
139        /// <param name="obj"></param>
140        /// <param name="dep"></param>
141        /// <param name="seconds"></param>

142        public static void Insert(string key, object obj, CacheDependency dep, int seconds)
143        {
144            Insert(key, obj, dep, seconds, CacheItemPriority.Normal);
145        }

146
147        /// <summary>
148        /// 按秒缓存对象 并建立具有优先级的依赖项
149        /// </summary>
150        /// <param name="key"></param>
151        /// <param name="obj"></param>
152        /// <param name="dep"></param>
153        /// <param name="seconds"></param>
154        /// <param name="priority"></param>

155        public static void Insert(string key, object obj, CacheDependency dep, int seconds, CacheItemPriority priority)
156        {
157            if (obj != null)
158            {
159                _cache.Insert(key, obj, dep, DateTime.Now.AddSeconds(Factor * seconds), TimeSpan.Zero, priority, null);
160            }

161
162        }

163
164
165        public static void MicroInsert(string key, object obj, int secondFactor)
166        {
167            if (obj != null)
168            {
169                _cache.Insert(key, obj, null, DateTime.Now.AddSeconds(Factor * secondFactor), TimeSpan.Zero);
170            }

171        }

172
173        /// <summary>
174        /// 最大时间缓存
175        /// </summary>
176        /// <param name="key"></param>
177        /// <param name="obj"></param>

178        public static void Max(string key, object obj)
179        {
180            Max(key, obj, null);
181        }

182
183        /// <summary>
184        /// 具有依赖项的最大时间缓存
185        /// </summary>
186        /// <param name="key"></param>
187        /// <param name="obj"></param>
188        /// <param name="dep"></param>

189        public static void Max(string key, object obj, CacheDependency dep)
190        {
191            if (obj != null)
192            {
193                _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.AboveNormal, null);
194            }

195        }

196
197        /// <summary>
198        /// Insert an item into the cache for the Maximum allowed time
199        /// </summary>
200        /// <param name="key"></param>
201        /// <param name="obj"></param>

202        public static void Permanent(string key, object obj)
203        {
204            Permanent(key, obj, null);
205        }

206
207        public static void Permanent(string key, object obj, CacheDependency dep)
208        {
209            if (obj != null)
210            {
211                _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.NotRemovable, null);
212            }

213        }

214
215        public static object Get(string key)
216        {
217            return _cache[key];
218        }

219
220        /// <summary>
221        /// Return int of seconds * SecondFactor
222        /// </summary>

223        public static int SecondFactorCalculate(int seconds)
224        {
225            // Insert method below takes integer seconds, so we have to round any fractional values
226            return Convert.ToInt32(Math.Round((double)seconds * SecondFactor));
227        }

228    }

229}

230

 

其实这个类就是一个单件模式的设计 和缓存的公共操作方法,其中CacheDependency表示建立缓存依赖项,CacheItemPriority表示缓存的优先级。S使用如下

 

 1public static CardShop.Model.Systems GetConfig() 
 2    {
 3        const string cacheKey = "WebConfig";
 4        CardShop.Model.Systems sampleCacheTable = Larry.Cache.BaseCache.Get(cacheKey) as CardShop.Model.Systems;
 5        if (sampleCacheTable == null)
 6        {
 7                                  OprationCheck.Message("第一次加载使用缓存");
 8            sampleCacheTable = model;
 9            Larry.Cache.BaseCache.Insert(cacheKey, sampleCacheTable, 24 * Larry.Cache.BaseCache.MinuteFactor);
10        }

11        else
12        {
13            OprationCheck.Message("已经加载了缓存不需要再加载");
14        }

15        return sampleCacheTable;
16    }

 

posted @ 2013-03-12 11:15  左正  阅读(324)  评论(0编辑  收藏  举报