在用非SqlServer数据库时,不能用.net自带的缓存类。那我们应该怎么做呢?
大致思路是:在application第一次启动的时候加载需要缓存的数据。然后每隔固定时间(比如1min)去更新缓存数据。
当需要查询的时候直接去查缓存中的时间,减少与DB交互。
具体看代码:
1.在Global中异步load所要缓存的数据:
首先定义一个全局的timer。
Timer t = null;
2.在Application_Start中启动一个线程去load所需数据:
protected void Application_Start() { //省略其他代码... Thread t = new Thread(Work); t.Start(); }
private void Work() { try { //log DateTime.Now System.Diagnostics.Stopwatch watcher = new System.Diagnostics.Stopwatch(); watcher.Start(); AdChina.Core.Helper.LogHelper.LogInfoFormat("start to load data from table:EA_CPS_REPORT_DATA... {0}", DateTime.Now); List<EaCpsReportData> reps = new DBHelper().GetInstance().Query<EaCpsReportData>("select * from EA_CPS_REPORT_DATA where status>-1").ToList<EaCpsReportData>(); Dictionary<int, EaCpsReportData> dic = reps.ToDictionary(o => o.SerialId); HttpRuntime.Cache.Add("diccpsreportdata", dic, null, System.Web.Caching.Cache.NoAbsoluteExpiration, System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null); watcher.Stop(); long time = watcher.ElapsedMilliseconds; AdChina.Core.Helper.LogHelper.LogInfoFormat("after {0} ms,load data completed. {1}", time, DateTime.Now); TimerCallback callback = new TimerCallback(GetData); int dueTime = int.Parse(System.Configuration.ConfigurationManager.AppSettings["CacheDueTime"]); t = new Timer(callback, dueTime, 0, dueTime); } catch (Exception e) { //log here } }
private object lockobject = new object(); //从DB获取变更数据,根据key去更新Dictionary。
private void GetData(object o) { try { Dictionary<int, EaCpsReportData> dic = HttpRuntime.Cache["diccpsreportdata"] as Dictionary<int, EaCpsReportData>; if (dic == null) return; //1.查到1min所有变更数据 int dueTime = (int)o * -2; List<EaCpsReportData> changed = new DBHelper().GetInstance().Query<EaCpsReportData>("select * from EA_CPS_REPORT_DATA where LAST_CHANGE >= @0 order by LAST_CHANGE", DateTime.Now.AddMilliseconds(dueTime)).ToList<EaCpsReportData>(); lock (lockobject) { //2.依次更新 foreach (var data in changed) { if (dic.ContainsKey(data.SerialId) && data.Status > 0) { dic[data.SerialId] = data; } else if (dic.ContainsKey(data.SerialId) && data.Status == -1) { dic.Remove(data.SerialId); } else if (!dic.ContainsKey(data.SerialId) && data.Status > 0) { dic.Add(data.SerialId, data); } } } HttpRuntime.Cache["diccpsreportdata"] = dic; if (changed.Count > 0)
{
//log here
} } catch (Exception e) { //log here } }
3.在查询的地方直接去查缓存里数据:
Dictionary<int, EaCpsReportData> dic = System.Web.HttpRuntime.Cache["diccpsreportdata"] as Dictionary<int, EaCpsReportData>; if (dic == null) { // query from db }