123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Web.Caching;
- using System.Threading;
- namespace Ant.ORM.Cache
- {
- /// <summary>
- /// 全局缓存类
- /// </summary>
- /// <example><code>
- /// 使用示例:
- /// 实例化: CacheManage cache=CacheManage.Instance;
- /// 添加: cache.Add("路过秋天",new MDataTable);
- /// 判断: if(cache.Contains("路过秋天"))
- /// {
- /// 获取: MDataTable table=cache.Get("路过秋天") as MDataTable;
- /// }
- /// </code></example>
- public class CacheManage
- {
- private readonly System.Web.HttpContext H = new System.Web.HttpContext(new System.Web.HttpRequest("Null.File", "http://cyq1162.cnblogs.com", String.Empty), new System.Web.HttpResponse(null));
- private System.Web.Caching.Cache theCache = null;
- private Dictionary<string, CacheDependencyInfo> cacheState = new Dictionary<string, CacheDependencyInfo>();
- private DateTime workTime;
- /// <summary>
- /// 缓存信息
- /// </summary>
- public Dictionary<string, CacheDependencyInfo> CacheInfo
- {
- get
- {
- return cacheState;
- }
- }
- private CacheManage()
- {
- theCache = H.Cache;
- Thread thread = new Thread(new ThreadStart(ClearState));
- thread.IsBackground = true;
- thread.Start();
- workTime = DateTime.Now.AddMinutes(5);
- }
- private void ClearState()
- {
- List<string> removeKeys = new List<string>();
- while (true)
- {
- try
- {
- Thread.Sleep(5 * 60 * 1000);//五分钟休眠时间
- if (theCache.Count != cacheState.Count)//准备同步
- {
- foreach (KeyValuePair<string, CacheDependencyInfo> item in cacheState)
- {
- if ((item.Value.CreaeTime.AddMinutes(4) < DateTime.Now && item.Value.CallCount < 2) || //缓存调用次数太少
- item.Value.CreaeTime.AddMinutes(item.Value.CacheMinutes) < DateTime.Now)//清过期cacheState进行同步
- {
- if (!removeKeys.Contains(item.Key))
- {
- removeKeys.Add(item.Key);
- }
- }
- }
- foreach (string key in removeKeys)
- {
- Remove(key);//移除
- }
- clearCount = removeKeys.Count;
- removeKeys.Clear();
- }
- workTime = DateTime.Now.AddMinutes(5);
- }
- catch
- {
- System.Threading.Thread.Sleep(TimeSpan.FromHours(1));
- }
- }
- }
- private int errorCount = 0;//缓存捕异常次数
- private int clearCount = 0;//清除的缓存数
- /// <summary>
- /// 缓存工作信息
- /// </summary>
- public string WorkInfo
- {
- get
- {
- return string.Format("try catch error:{0}(times)--clear count:{1}--next clear work time at:{2}", errorCount, clearCount, workTime);
- }
- }
- /// <summary>
- /// 获和缓存总数
- /// </summary>
- public int Count
- {
- get
- {
- return theCache == null ? 0 : theCache.Count;
- }
- }
- /// <summary>
- /// 返回唯一实例
- /// </summary>
- public static CacheManage Instance
- {
- get
- {
- return Shell.instance;
- }
- }
- class Shell
- {
- internal static readonly CacheManage instance = new CacheManage();
- }
- /// <summary>
- /// 还可用的缓存百分比
- /// </summary>
- public long RemainMemoryPercentage
- {
- get
- {
- return theCache.EffectivePercentagePhysicalMemoryLimit;
- }
- }
- /// <summary>
- /// 还可用的缓存字节数
- /// </summary>
- public long RemainMemoryBytes
- {
- get
- {
- return theCache.EffectivePrivateBytesLimit;
- }
- }
- /// <summary>
- /// 获得一个Cache对象
- /// </summary>
- /// <param name="key">标识</param>
- /// <returns></returns>
- public object Get(string key)
- {
- if (Contains(key))
- {
- try
- {
- cacheState[key].CallCount++;
- }
- catch
- {
- errorCount++;
- }
- return theCache[key];
- }
- return null;
- }
- /// <summary>
- /// 是否存在缓存
- /// </summary>
- /// <param name="key">标识</param>
- /// <returns></returns>
- public bool Contains(string key)
- {
- if (theCache[key] != null)
- {
- return true;
- }
- else
- {
- if (cacheState.ContainsKey(key))
- {
- try
- {
- cacheState.Remove(key);
- }
- catch
- {
- errorCount++;
- }
- }
- return false;
- }
- }
- /// <summary>
- /// 添加一个Cache对象
- /// </summary>
- /// <param name="key">标识</param>
- /// <param name="value">对象值</param>
- public void Add(string key, object value)
- {
- Add(key, value, null, 0);
- }
- public void Add(string key, object value, string filePath)
- {
- Add(key, value, filePath, 0);//再插入Cache
- }
- public void Add(string key, object value, string filePath, double cacheTimeMinutes)
- {
- if (Contains(key))
- {
- Remove(key);
- }
- Insert(key, value, filePath, cacheTimeMinutes);//再插入Cache
- }
- /// <summary>
- /// 缓存设置:有则更新,无则添加
- /// </summary>
- /// <param name="key"></param>
- /// <param name="value"></param>
- public void Set(string key, object value)
- {
- if (Contains(key))
- {
- theCache[key] = value;
- }
- else
- {
- Insert(key, value, null, 0);//再插入Cache
- }
- }
- /// <summary>
- /// 更新缓存,缓存存在则更更新,不存在则跳过
- /// </summary>
- public void Update(string key, object value)
- {
- if (Contains(key))
- {
- theCache[key] = value;
- }
- }
- /// <summary>
- /// 相对底层Cache添加方法,添加一个Cache请用Add方法
- /// </summary>
- /// <param name="key">标识</param>
- /// <param name="value">对象值</param>
- /// <param name="filePath">文件依赖路径</param>
- /// <param name="cacheTimeMinutes">缓存分钟数</param>
- private void Insert(string key, object value, string filePath, double cacheTimeMinutes)
- {
- CacheDependency theCacheDependency = null;
- if (!string.IsNullOrEmpty(filePath))
- {
- theCacheDependency = new CacheDependency(filePath);
- }
- double cacheTime = cacheTimeMinutes;
- if (cacheTimeMinutes == 0)
- {
- cacheTime = 30;
- }
- theCache.Insert(key, value == null ? string.Empty : value, theCacheDependency, DateTime.Now.AddMinutes(cacheTime), TimeSpan.Zero, CacheItemPriority.Default, null);
- CacheDependencyInfo info = new CacheDependencyInfo(theCacheDependency, cacheTime);
- if (cacheState.ContainsKey(key))
- {
- cacheState[key] = info;
- }
- else
- {
- try
- {
- cacheState.Add(key, info);
- }
- catch { }
- }
- }
- /// <summary>
- /// 删除一个Cache对象
- /// </summary>
- /// <param name="key">标识</param>
- public void Remove(string key)
- {
- if (Contains(key))//检测存在时中会自动清除cacheState
- {
- try
- {
- theCache.Remove(key);
- cacheState.Remove(key);
- }
- catch
- {
- errorCount++;
- }
- }
- }
- /// <summary>
- /// 清除所有缓存
- /// </summary>
- public void Clear()
- {
- try
- {
- foreach (KeyValuePair<string, CacheDependencyInfo> item in cacheState)
- {
- theCache.Remove(item.Key);
- }
- cacheState.Clear();
- }
- catch
- {
- errorCount++;
- }
- }
- /// <summary>
- /// 用户手动设置缓存对象已更改
- /// </summary>
- /// <param name="key"></param>
- /// <param name="change"></param>
- public void SetChange(string key, bool change)
- {
- if (cacheState.ContainsKey(key) && Contains(key))
- {
- CacheDependencyInfo info = cacheState[key];
- if (info != null)
- {
- info.UserSetChange(change);
- }
- }
- else
- {
- Add("Ant.ORM.Cache:Temp_" + key, change, null, 0.1);//缓存失效时,产生6秒的key缓冲
- }
- }
- /// <summary>
- /// 获取缓存对象是否已被用户手动设置更改
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- public bool GetHasChanged(string key)
- {
- if (cacheState.ContainsKey(key) && Contains(key))
- {
- CacheDependencyInfo info = cacheState[key];
- if (info != null)
- {
- return info.IsChanged ? false : info.UserChange;
- }
- }
- else if (Contains("Ant.ORM.Cache:Temp_" + key))
- {
- return (bool)theCache.Get("Ant.ORM.Cache:Temp_" + key);
- }
- return false;
- }
- }
- /// <summary>
- /// 缓存依赖信息
- /// </summary>
- public class CacheDependencyInfo
- {
- public int CallCount = 0;
- /// <summary>
- /// 缓存产生的时间
- /// </summary>
- public DateTime CreaeTime;
- /// <summary>
- /// 缓存多少分钟
- /// </summary>
- public Double CacheMinutes = 0;
- DateTime CacheChangeTime = DateTime.MinValue;
- CacheDependency FileDependency = null;
- public CacheDependencyInfo(CacheDependency dependency, double cacheMinutes)
- {
- if (dependency != null)
- {
- FileDependency = dependency;
- CacheChangeTime = FileDependency.UtcLastModified;
- }
- CreaeTime = DateTime.Now;
- CacheMinutes = cacheMinutes;
- }
- /// <summary>
- /// 系统文件依赖是否发生改变
- /// </summary>
- public bool IsChanged
- {
- get
- {
- if (FileDependency != null && (FileDependency.HasChanged || CacheChangeTime != FileDependency.UtcLastModified))
- {
- CacheChangeTime = FileDependency.UtcLastModified;
- return true;
- }
- return false;
- }
- }
- internal bool UserChange = false;
- public void UserSetChange(bool change)
- {
- UserChange = IsChanged ? false : change;
- }
- }
- }
|