/// <summary> /// 重新刷新,如果内存中有数据,则直接刷新,否则删除文件及缓存 /// </summary> /// <param name="key">缓存键</param> /// <returns></returns> public static void ReFlush(string key) { try { var result = default(T); CacheEntityObject e = null; lock (LockXXXUltimate) { CacheMutexMapping.Remove(key);//清空掉缓存锁中的数据,防止自动更新 e = CacheTable.TryGetValue(key, out e) && e != null && e.Value != null && e.Value != default(T) ? e : null; } if (e != null)//如果内存中有数据,则执行相应的操作 { try { if ((result = e.Execute.Invoke()) != null && result != default(T)) { lock (LockXXXUltimate) { e.Value = result; e.Updatetime = DateTime.Now; CacheTable[e.Key] = e; _W(e.Key, result);//同时更新文件 } } } catch (Exception ex) { Log("[ReFlush] " + ex.Message.ToString()); } } else//如果内存中不存在,则删除文件,清空缓存 { var filename = Path.Combine(BaseDirectory, key + ".cache"); if (System.IO.File.Exists(filename)) { System.IO.File.Delete(filename);//删除缓存文件 } lock (LockXXXUltimate) { if (CacheTable.ContainsKey(key)) { CacheTable.Remove(key);//清空缓存中的数据 } } } } catch (Exception ex) { Log("[ReFlush] Exception:" + ex.Message.ToString()); } }
/// <summary> /// 每日更新一次刷新 /// </summary> /// <param name="key">缓存键,格式需要符合文件命名格式</param> /// <param name="fun">委托执行方法</param> /// <param name="ts">更新时间,格式:00:00:00</param> /// <returns></returns> public static T FlushDaily(string key, Func <T> fun, TimeSpan ts) { //return fun(); var e = default(T); var o = new CacheEntityObject(); o.Key = key; o.Timeout = ts; o.IsDaily = true; o.Value = e; o.Updatetime = DateTime.MinValue; o.Execute = fun; //o.Initialed = false; return(TryParser(o, out e) ? e : default(T)); }
/// <summary> /// 调度 /// </summary> private static void Scheduling() { string[] keys = null; //读取全部数据 //using (__lockXXXUltimate.ReadOnlyLock()) lock (LockXXXUltimate) { keys = new string[CacheTable.Keys.Count]; CacheTable.Keys.CopyTo(keys, 0); } foreach (var key in keys) { CacheEntityObject e = null; lock (LockXXXUltimate)//调度线程先进入锁状态,此时还在还在更新中,则退出 { if (!CacheMutexMapping.Contains(key)) { //开始遍历每一条记录 DateTime tick = DateTime.Now; //根据Key读取数据信息 e = CacheTable.TryGetValue(key, out e) && e != null && e.Value != null && e.Value != default(T) ? e : null; //判断当前是否可以运行 if (e != null && e.IsDaily && e.Updatetime < DateTime.Now.Date.Add(e.Timeout) && DateTime.Now.Date.Add(e.Timeout) < tick) { //当前文件最后更新时间小于更新点,且当前时间大于更新点 // 9:00运行,更新为上一次8点,且当前为9:01,则可以运行 CacheMutexMapping.Add(key); CacheQueue.Enqueue(key); } else if (e != null && !e.IsDaily && tick.Subtract(e.Updatetime).TotalSeconds > e.Timeout.TotalSeconds) { //根据上一次的运行时间作为更新对比时间 CacheMutexMapping.Add(key); CacheQueue.Enqueue(key); } } } } }
/// <summary> /// 解析数据对象 /// </summary> /// <param name="o"></param> /// <param name="result"></param> /// <returns></returns> private static bool TryParser(CacheEntityObject o, out T result) { CacheEntityObject e = null; result = default(T); #region 从内存中加载数据 //using (__lockXXXUltimate.ReadOnlyLock())//并行只读锁 lock (LockXXXUltimate) { e = CacheTable.TryGetValue(o.Key, out e) && e != null && e.Value != null && e.Value != default(T) ? e : null; } #endregion #region 内存中不存在数据,则从文件中读取 if (e == null || e.Value == null || e.Value == default(T))//如果内存中不存在 { lock (LockXXXUltimate) { e = CacheTable.TryGetValue(o.Key, out e) && e != null && e.Value != null && e.Value != default(T) && e.Updatetime >= DateTime.MinValue ? e : null; if (e == null || e.Value == null || e.Value == default(T))//如果内存中不存在 { DateTime w = DateTime.MinValue; result = _R(o.Key, out w); //从文件加载 e = new CacheEntityObject(); //创建一个新对象,添加到缓存中 e.Key = o.Key; e.IsDaily = o.IsDaily; e.Timeout = o.Timeout; e.Updatetime = o.Updatetime; e.Execute = o.Execute; e.Value = result; e.Updatetime = w; //更新当前从缓存中读取的数据 CacheTable[e.Key] = e; //更新到缓存中 } } } #endregion #region 在内在或文件中读取到数据 if (e != null && e.Value != null && e.Value != default(T) && e.Updatetime != DateTime.MinValue)//如果内存中不存在 { result = e.Value; return(true); } #endregion #region 如果内存和文件中都不存在当前的数据,则直接调用回调,填充到内存及文件中 try { if ((result = o.Execute.Invoke()) != null && result != default(T)) { lock (LockXXXUltimate) { _W(o.Key, result);//同时更新文件 o.Value = result; o.Updatetime = DateTime.Now; CacheTable[o.Key] = o; CacheMutexMapping.Remove(o.Key); return(true); } } } catch (Exception ex) { lock (LockXXXUltimate) { CacheMutexMapping.Remove(o.Key); } Log("[Executing] " + ex.Message.ToString()); } #endregion return(false); }
/// <summary> /// 执行 /// </summary> private static void Executing() { var key = string.Empty; CacheEntityObject e = null; var result = default(T); //从队列中读取一条记录 lock (LockXXXUltimate) { if (CacheQueue.Count > 0) { key = CacheQueue.Dequeue(); if (!CacheMutexMapping.Contains(key))//队列及缓存锁中都存在才能执行 { key = string.Empty; } } } if (string.IsNullOrEmpty(key)) { return; } //读取数据信息 //using (__lockXXXUltimate.ReadOnlyLock())//并行只读锁 lock (LockXXXUltimate) { e = CacheTable.TryGetValue(key, out e) && e != null && e.Value != null && e.Value != default(T) ? e : null; } if (e == null) { lock (LockXXXUltimate) { CacheMutexMapping.Remove(key);//在数据执行完成清空数据,等待下一次完成 } Log("[Executing] [" + key + "] is null"); return; } try { //执行 if ((result = e.Execute.Invoke()) != null && result != default(T)) { lock (LockXXXUltimate) { e.Value = result; //更新结果 e.Updatetime = DateTime.Now; //更新最后更新时间 CacheTable[e.Key] = e; CacheMutexMapping.Remove(key); //在数据执行完成清空数据,等待下一次完成 _W(e.Key, result); //同时更新文件 } //Log("[Executing] [" + e.Key + "] [" + e.Updatetime.ToString("yyyy-MM-dd HH:mm:ss") + "] [" + (e.IsDaily ? e.Timeout.ToString() : ((int)e.Timeout.TotalSeconds).ToString()) + "] OK..."); } } catch (System.Threading.ThreadAbortException) { lock (LockXXXUltimate) { CacheMutexMapping.Remove(key);//在数据执行完成清空数据,等待下一次完成 } } catch (Exception ex) { lock (LockXXXUltimate) { CacheMutexMapping.Remove(key);//在数据执行完成清空数据,等待下一次完成 } Log("[Executing] " + ex.Message.ToString()); } }