<>静态字段缓存基本使用
/// <summary> /// 1 客户端缓存-CDN缓存-反向代理缓存-本地缓存 /// 2 本地缓存原理和手写基础实现 /// 3
缓存更新/过期/多线程测试 /// 4 缓存类库封装和缓存应用总结 /// </summary> /// <param name="args"></param>
static void Main(string[] args) { try { Console.WriteLine("开发进阶/蜕变架构!"); {
Console.WriteLine("***************DBHelper*****************"); for (int i = 0; i
< 5; i++) //会重复查询数据 { Console.WriteLine($"获取{nameof(DBHelper)} {i}次
{DateTime.Now.ToString("yyyyMMdd HHmmss.fff")}"); List<Program> programList =
null; string key = $"{nameof(Program)}_DBHelper.Query_{123}"; programList =
CustomCache.GetT<List<Program>>(key, () => { return DBHelper.Query<Program>(123)
; }); } } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read
(); } /// <summary> ///模拟数据库查询 /// </summary> public class DBHelper { ///
<summary> /// 1 耗时耗资源 /// 2 参数固定时,结果不变 /// </summary> /// <typeparam
name="T"></typeparam> /// <param name="index"></param> /// <returns></returns>
public static List<T> Query<T>(int index) { Console.WriteLine("This is {0}
Query", typeof(DBHelper)); long lResult = 0; //耗时耗资源 for (int i = index; i < 1
_000_000_000; i++) { lResult += i; } ///只要Index不变 返回值是不变的! List<T> tList = new
List<T>(); for (int i = 0; i < index % 3; i++) { tList.Add(default(T)); } return
tList; } } public class CustomCache { /// <summary> /// 字典缓存 ///
static:不会被Gc回收; /// Private:不让外部访问他 /// </summary> private static Dictionary<
string, object> CustomCacheDictionary = new Dictionary<string, object>(); public
static void Add(string key, object value) { CustomCacheDictionary.Add(key, value
); } public static T Get<T>(string key) { return (T)CustomCacheDictionary[key];
} public static bool Exists(string key) { return CustomCacheDictionary.
ContainsKey(key); } public static T GetT<T>(string key, Func<T> func) { T t =
default(T); if (!Exists(key)) { t = func.Invoke(); Add(key, t); } else { t = Get
<T>(key); } return t; } }
<>cache缓存封装
/// <summary> /// Cache manager interface /// </summary> public interface
ICache { /// <summary> /// Gets or sets the value associated with the specified
key. /// </summary> /// <typeparam name="T">Type</typeparam> /// <param
name="key">The key of the value to get.</param> /// <returns>The value
associated with the specified key.</returns> T Get<T>(string key); /// <summary>
/// Adds the specified key and object to the cache. /// </summary> /// <param
name="key">key</param> /// <param name="data">Data</param> /// <param
name="cacheTime">Cache time</param> void Add(string key, object data, int
cacheTime= 30); /// <summary> /// Gets a value indicating whether the value
associated with the specified key is cached /// </summary> /// <param
name="key">key</param> /// <returns>Result</returns> bool Contains(string key);
/// <summary> /// Removes the value with the specified key from the cache ///
</summary> /// <param name="key">/key</param> void Remove(string key); ///
<summary> /// Clear all cache data /// </summary> void RemoveAll(); object this[
string key] { get; set; } int Count { get; } } /// <summary> ///
MemoryCacheCache /// </summary> public class MemoryCacheCache : ICache { public
MemoryCacheCache() { } protected ObjectCache Cache { get { return MemoryCache.
Default; } } /// <summary> /// 读取缓存 /// </summary> /// <typeparam
name="T"></typeparam> /// <param name="key"></param> /// <returns></returns>
public T Get<T>(string key) { if (Cache.Contains(key)) { return (T)Cache[key]; }
else { return default(T); } } public object Get(string key) { return Cache[key];
} /// <summary> /// 增加缓存 /// </summary> /// <param name="key"></param> ///
<param name="data"></param> /// <param name="cacheTime">分钟</param> public void
Add(string key, object data, int cacheTime = 30) { if (data == null) return; var
policy= new CacheItemPolicy(); policy.AbsoluteExpiration = DateTime.Now +
TimeSpan.FromMinutes(cacheTime); Cache.Add(new CacheItem(key, data), policy); }
/// <summary> /// 是否包含 /// </summary> /// <param name="key"></param> ///
<returns></returns> public bool Contains(string key) { return Cache.Contains(key
); } public int Count { get { return (int)(Cache.GetCount()); } } /// <summary>
/// 单个清除 /// </summary> /// <param name="key">/key</param> public void Remove(
string key) { Cache.Remove(key); } /// <summary> /// 正则表达式移除 /// </summary> ///
<param name="pattern">pattern</param> public void RemoveByPattern(string pattern
) { var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.
Compiled| RegexOptions.IgnoreCase); var keysToRemove = new List<String>();
foreach (var item in Cache) if (regex.IsMatch(item.Key)) keysToRemove.Add(item.
Key); foreach (string key in keysToRemove) { Remove(key); } } /// <summary> ///
根据键值返回缓存数据 /// </summary> /// <param name="key"></param> /// <returns></returns>
public object this[string key] { get { return Cache.Get(key); } set { Add(key,
value); } } /// <summary> /// 清除全部数据 /// </summary> public void RemoveAll() {
foreach (var item in Cache) Remove(item.Key); } }
<>缓存管理中心
public class CacheManager { #region Identity private CacheManager() { } private
static ICache cache = null; static CacheManager() { Console.WriteLine(
"开始缓存的初始化....."); //可以创建不同的cache对象 cache = (ICache)Activator.CreateInstance(
typeof(MemoryCacheCache)); // 这里可以根据配置文件来选择 //cache =
(ICache)Activator.CreateInstance(typeof(CustomerCache)); } #endregion Identity #
region ICache /// <summary> /// 当前缓存数据项的个数 /// </summary> public static int
Count{ get { return cache.Count; } } /// <summary> /// 如果缓存中已存在数据项键值,则返回true
/// </summary> /// <param name="key">数据项键值</param> ///
<returns>数据项是否存在</returns> public static bool Contains(string key) { return
cache.Contains(key); } /// <summary> /// 获取缓存数据 /// </summary> /// <param
name="key"></param> /// <returns></returns> public static T GetData<T>(string
key) { return cache.Get<T>(key); } /// <summary> /// /// </summary> ///
<typeparam name="T"></typeparam> /// <param name="key">缓存的项</param> /// <param
name="acquire">没有缓存的时候获取数据的方式</param> /// <param name="cacheTime">单位分钟
默认30</param> /// <returns></returns> public static T Get<T>(string key, Func<T>
acquire, int cacheTime = 30) { if (!cache.Contains(key)) { T result = acquire.
Invoke(); cache.Add(key, result, cacheTime); } return GetData<T>(key); } ///
<summary> /// 添加缓存数据。 /// 如果另一个相同键值的数据已经存在,原数据项将被删除,新数据项被添加。 /// </summary> ///
<param name="key">缓存数据的键值</param> /// <param name="value">缓存的数据,可以为null值</param>
/// <param name="expiratTime">缓存过期时间间隔(单位:分钟)</param> public static void Add(
string key, object value, int expiratTime = 30) { if (Contains(key)) cache.
Remove(key); cache.Add(key, value, expiratTime); } /// <summary> /// 删除缓存数据项
/// </summary> /// <param name="key"></param> public static void Remove(string
key) { cache.Remove(key); } /// <summary> /// 删除所有缓存数据项 /// </summary> public
static void RemoveAll() { cache.RemoveAll(); } #endregion }
缓存优化
/// <summary> /// 永不过期:当前就是 /// 绝对过期:过了多长时间以后,就过期了 就不能用了 ///
滑动过期:设定好过期时间后,如果在有效期内使用过,就往后滑动 /// 1.Value;数据; /// 2.过期时间点: /// 3.滑动时间 ///
普通cache /// </summary> public class CustomCache { static CustomCache() //CLR调用
整个进程执行且只执行一次 { Task.Run(() => // { while (true) //死循环来判断 { try { List<string>
delKeyList= new List<string>(); lock (obj_Lock) { foreach (var key in
CustomCacheDictionary.Keys) { DataModel model = CustomCacheDictionary[key]; if (
model.Deadline < DateTime.Now && model.ObsloteType != ObsloteType.Never) {
delKeyList.Add(key); } } } delKeyList.ForEach(key => Remove(key)); } catch (
Exception ex) { Console.WriteLine(ex.Message); throw; } } }); } /// <summary>
/// static:不会被Gc回收; /// Private:不让外部访问他 /// </summary> private static Dictionary
<string, DataModel> CustomCacheDictionary = new Dictionary<string, DataModel>();
private static readonly object obj_Lock = new object(); /// <summary> ///
默认你是不过期 /// </summary> /// <param name="key"></param> /// <param
name="value"></param> public static void Add(string key, object value) { lock (
obj_Lock) CustomCacheDictionary.Add(key, new DataModel() { Value = value,
ObsloteType= ObsloteType.Never }); } /// <summary> /// 绝对过期 /// </summary> ///
<param name="key"></param> /// <param name="value"></param> /// <param
name="timeOutSecond"></param> public static void Add(string key, object value,
int timeOutSecond) //3000 { lock (obj_Lock) CustomCacheDictionary.Add(key, new
DataModel() { Value = value, ObsloteType = ObsloteType.Absolutely, Deadline =
DateTime.Now.AddSeconds(timeOutSecond) }); ; } public static void Add(string key
, object value, TimeSpan durtion) { lock (obj_Lock) CustomCacheDictionary.Add(
key, new DataModel() { Value = value, ObsloteType = ObsloteType.Relative,
Deadline= DateTime.Now.Add(durtion), Duraton = durtion }); ; ; } //清楚所有缓存,殃及池鱼!
public static void RemoveAll() { lock (obj_Lock) CustomCacheDictionary.Clear();
//字典中的所有内容全部被清理到 } public static void Remove(string key) { lock (obj_Lock)
CustomCacheDictionary.Remove(key); } public static void RemoveCondition(Func<
string, bool> func) { List<string> keyList = new List<string>(); lock (obj_Lock)
foreach (var key in CustomCacheDictionary.Keys) { if (func.Invoke(key)) {
keyList.Add(key); } } keyList.ForEach(s => Remove(s)); } public static T Get<T>(
string key) { return (T)(CustomCacheDictionary[key]).Value; } public static bool
Exists(string key) { if (CustomCacheDictionary.ContainsKey(key)) { DataModel
model= CustomCacheDictionary[key]; if (model.ObsloteType == ObsloteType.Never) {
return true; } else if (model.Deadline < DateTime.Now) // { lock (obj_Lock) {
CustomCacheDictionary.Remove(key); return false; } } else { if (model.
ObsloteType== ObsloteType.Relative) { model.Deadline = DateTime.Now.Add(model.
Duraton); } return true; } } else { return false; } } public static T GetT<T>(
string key, Func<T> func) { T t = default(T); if (!Exists(key)) { t = func.
Invoke(); Add(key, t); } else { t = Get<T>(key); } return t; } } /// <summary>
/// 线程安全cache /// </summary> public class CustomCacheNew { static CustomCacheNew
() // { Task.Run(() => // { while (true) //死循环来判断 { try { //Thread.Sleep(60 *
1000 * 10); //十分钟后开始清理缓存 List<string> delKeyList = new List<string>(); foreach (
var key in CustomCacheDictionary.Keys) { DataModel model = CustomCacheDictionary
[key]; if (model.Deadline < DateTime.Now && model.ObsloteType != ObsloteType.
Never) // { delKeyList.Add(key); } } delKeyList.ForEach(key => Remove(key)); }
catch (Exception ex) { Console.WriteLine(ex.Message); throw; } } }); } ///
<summary> /// static:不会被Gc回收; /// Private:不让外部访问他 /// /// 线程安全字典 /// </summary>
private static ConcurrentDictionary<string, DataModel> CustomCacheDictionary =
new ConcurrentDictionary<string, DataModel>(); /// <summary> /// 默认你是不过期 ///
</summary> /// <param name="key"></param> /// <param name="value"></param>
public static void Add(string key, object value) { CustomCacheDictionary.TryAdd(
key, new DataModel() { Value = value, ObsloteType = ObsloteType.Never }); } ///
<summary> /// 绝对过期 /// </summary> /// <param name="key"></param> /// <param
name="value"></param> /// <param name="timeOutSecond"></param> public static
void Add(string key, object value, int timeOutSecond) //3000 {
CustomCacheDictionary.TryAdd(key, new DataModel() { Value = value, ObsloteType =
ObsloteType.Absolutely, Deadline = DateTime.Now.AddSeconds(timeOutSecond) }); ;
} public static void Add(string key, object value, TimeSpan durtion) {
CustomCacheDictionary.TryAdd(key, new DataModel() { Value = value, ObsloteType =
ObsloteType.Relative, Deadline = DateTime.Now.Add(durtion), Duraton = durtion }
); ; ; } //清楚所有缓存,殃及池鱼! public static void RemoveAll() { CustomCacheDictionary.
Clear();//字典中的所有内容全部被清理到 } public static void Remove(string key) { DataModel
data= null; CustomCacheDictionary.TryRemove(key, out data); } public static T
Get<T>(string key) { return (T)(CustomCacheDictionary[key]).Value; } ///
<summary> /// 判断是否存在 /// </summary> /// <param name="key"></param> ///
<returns></returns> public static bool Exists(string key) { if (
CustomCacheDictionary.ContainsKey(key)) { DataModel model =
CustomCacheDictionary[key]; if (model.ObsloteType == ObsloteType.Never) { return
true; } else if (model.Deadline < DateTime.Now) // { DataModel data = null;
CustomCacheDictionary.TryRemove(key, out data); return false; } else { if (model
.ObsloteType == ObsloteType.Relative) { model.Deadline = DateTime.Now.Add(model.
Duraton); } return true; } } else { return false; } } public static T GetT<T>(
string key, Func<T> func) { T t = default(T); if (!Exists(key)) { t = func.
Invoke(); Add(key, t); } else { t = Get<T>(key); } return t; } } internal class
DataModel { public object Value { get; set; } public ObsloteType ObsloteType {
get; set; } public DateTime Deadline { get; set; } public TimeSpan Duraton { get
; set; } } public enum ObsloteType { Never, Absolutely, Relative } /// <summary>
/// 解决性能问题 /// </summary> public class CustomCacheNewproblem { private static
List<Dictionary<string, DataModel>> dicCacheList = new List<Dictionary<string,
DataModel>>(); private static List<object> lockList = new List<object>(); public
static int CupNum = 0; static CustomCacheNewproblem() { CupNum = 3;//模拟获取获取CPU片数
//动态生成字典 for (int i = 0; i < CupNum; i++) { dicCacheList.Add(new Dictionary<
string, DataModel>()); //CPU 有几片 就来几个字典 lockList.Add(new object());//没个字典对应一个锁 }
Task.Run(() => // { while (true) //死循环来判断 { try { for (int i = 0; i < CupNum; i
++) { lock (lockList[i]) { //Thread.Sleep(60 * 1000 * 10); //十分钟后开始清理缓存 List<
string> delKeyList = new List<string>(); foreach (var key in dicCacheList[i].
Keys) { DataModel model = dicCacheList[i][key]; if (model.Deadline < DateTime.
Now&& model.ObsloteType != ObsloteType.Never) // { delKeyList.Add(key); } }
delKeyList.ForEach(key => dicCacheList[i].Remove(key)); } } } catch (Exception
ex) { Console.WriteLine(ex.Message); throw; } } }); } /// <summary> /// 默认你是不过期
/// </summary> /// <param name="key"></param> /// <param name="value"></param>
public static void Add(string key, object value) { int hash = key.GetHashCode()
* (-1); //只要字符串变,hash值不变! int index = hash % CupNum; lock (lockList[index])
dicCacheList[index].Add(key, new DataModel() { Value = value, ObsloteType =
ObsloteType.Never }); } /// <summary> /// 绝对过期 /// </summary> /// <param
name="key"></param> /// <param name="value"></param> /// <param
name="timeOutSecond"></param> public static void Add(string key, object value,
int timeOutSecond) //3000 { int hash = key.GetHashCode() * (-1);
//只要字符串变,hash值不变! int index = hash % CupNum; lock (lockList[index]) dicCacheList
[index].Add(key, new DataModel() { Value = value, ObsloteType = ObsloteType.
Absolutely, Deadline = DateTime.Now.AddSeconds(timeOutSecond) }); ; } public
static void Add(string key, object value, TimeSpan durtion) { int hash = key.
GetHashCode() * (-1); //只要字符串变,hash值不变! int index = hash % CupNum; lock (
lockList[index]) dicCacheList[index].Add(key, new DataModel() { Value = value,
ObsloteType= ObsloteType.Relative, Deadline = DateTime.Now.Add(durtion), Duraton
= durtion }); ; ; } //清楚所有缓存,殃及池鱼! public static void RemoveAll() { for (int i =
0; i < CupNum; i++) { dicCacheList[i].Clear(); } } public static void Remove(
string key) { int hash = key.GetHashCode() * (-1); //只要字符串变,hash值不变! int index =
hash% CupNum; if (dicCacheList[index].ContainsKey(key)) { dicCacheList[index].
Remove(key); } } public static T Get<T>(string key) { int hash = key.GetHashCode
() * (-1); //只要字符串变,hash值不变! int index = hash % CupNum; return (T)(dicCacheList[
index][key]).Value; } /// <summary> /// 判断是否存在 /// </summary> /// <param
name="key"></param> /// <returns></returns> public static bool Exists(string key
) { int hash = key.GetHashCode() * (-1); //只要字符串变,hash值不变! int index = hash %
CupNum; if (dicCacheList[index].ContainsKey(key)) { DataModel model =
dicCacheList[index][key]; if (model.ObsloteType == ObsloteType.Never) { return
true; } else if (model.Deadline < DateTime.Now) // { dicCacheList[index].Remove(
key); return false; } else { if (model.ObsloteType == ObsloteType.Relative) {
model.Deadline = DateTime.Now.Add(model.Duraton); } return true; } } else {
return false; } } public static T GetT<T>(string key, Func<T> func) { T t =
default(T); if (!Exists(key)) { t = func.Invoke(); Add(key, t); } else { t = Get
<T>(key); } return t; } }