缓存管理
Posted zfylzl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了缓存管理相关的知识,希望对你有一定的参考价值。
1.创建一个全局缓存基类接口ICacheBase<T>
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Linq; 5 using System.Text; 6 7 namespace WQB.Caching 8 { 9 /// <summary> 10 /// 全局缓存基类。 11 /// </summary> 12 public interface ICacheBase<T> 13 { 14 15 /// <summary> 16 /// 获取或设置缓存过期时间,单位秒。 17 /// </summary> 18 uint ExpiredSeconds { get; set; } 19 /// <summary> 20 /// 获取或设置缓存键 21 /// </summary> 22 string CacheKey { get;} 23 24 /// <summary> 25 /// 设置缓存数据 26 /// </summary> 27 /// <returns></returns> 28 bool InsertCache(); 29 30 /// <summary> 31 /// 获取数据缓存 32 /// </summary> 33 /// <returns></returns> 34 T GetCacheData(); 35 36 /// <summary> 37 /// 清除缓存 38 /// </summary> 39 /// <returns></returns> 40 bool RemoveCache(); 41 42 } 43 }
2.创建一个系统缓存接口ICaching
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace WQB.Caching 7 { 8 /// <summary> 9 /// 系统缓存接口 10 /// </summary> 11 public interface ICaching 12 { 13 /// <summary> 14 /// 删除所有的缓存 15 /// </summary> 16 /// <returns></returns> 17 bool Clear(); 18 /// <summary> 19 /// 根据key值获取缓存 20 /// </summary> 21 /// <param name="key"></param> 22 /// <returns></returns> 23 object Get(string key); 24 /// <summary> 25 /// 根据key值和类型获取具体类型的缓存 26 /// </summary> 27 /// <typeparam name="T"></typeparam> 28 /// <param name="key"></param> 29 /// <returns></returns> 30 T Get<T>(string key); 31 /// <summary> 32 /// 添加缓存,过期时间默认为5个小时 33 /// </summary> 34 /// <param name="key"></param> 35 /// <param name="obj"></param> 36 /// <returns></returns> 37 bool Insert(string key, object obj); 38 39 /// <summary> 40 /// 添加缓存,同时设置缓存过期时间 41 /// </summary> 42 /// <param name="key"></param> 43 /// <param name="obj"></param> 44 /// <param name="expiredSeconds">缓存过期时间,单位秒</param> 45 /// <returns></returns> 46 bool Insert(string key, object obj, int expiredSeconds); 47 /// <summary> 48 /// 49 /// </summary> 50 /// <param name="key"></param> 51 /// <returns></returns> 52 bool Remove(string key); 53 } 54 }
3.创建一个全局缓存基类CacheBase<T>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace WQB.Caching 7 { 8 /// <summary> 9 /// 全局缓存基类。 10 /// 为了更好的管理所有的全局缓存缓存数据,避免缓存键冲突和重复缓存,所有的全局缓存键统一放在这边。 11 /// </summary> 12 public class CacheBase<T> : ICacheBase<T> 13 { 14 internal WQB.Caching.ICaching cachinger = WQB.Caching.CachingManager.GetCachingger(); 15 16 /// <summary> 17 /// 缓存键 18 /// </summary> 19 string _cachekey; 20 21 /// <summary> 22 /// 缓存过期时间,单位秒。 23 /// </summary> 24 uint _expiredSeconds; 25 26 public CacheBase() 27 { 28 ExpiredSeconds = 60 * 10; 29 } 30 /// <summary> 31 /// 获取或设置缓存名称 32 /// </summary> 33 public string CacheKey { get { return _cachekey; } set { _cachekey = value; } } 34 35 /// <summary> 36 /// 获取或设置缓存过期时间,单位秒。最小值为3秒。 37 /// </summary> 38 public uint ExpiredSeconds { get { return _expiredSeconds; } set { _expiredSeconds = Math.Max(value,3); } } 39 40 /// <summary> 41 /// 获取缓存数据源 42 /// </summary> 43 /// <returns></returns> 44 public virtual T GetCacheSource() 45 { 46 return (T)(new object()); 47 } 48 49 /// <summary> 50 /// 设置缓存数据 51 /// </summary> 52 /// <returns></returns> 53 public bool InsertCache() 54 { 55 T data = GetCacheSource(); 56 return cachinger.Insert(CacheKey, data,(int)ExpiredSeconds); 57 } 58 59 /// <summary> 60 /// 获取数据缓存 61 /// </summary> 62 /// <returns></returns> 63 public virtual T GetCacheData() 64 { 65 object obj = cachinger.Get(CacheKey); 66 if(obj == null) 67 { 68 T data = GetCacheSource(); 69 cachinger.Insert(CacheKey, data, (int)ExpiredSeconds); 70 return data; 71 } 72 return (T)obj; 73 } 74 75 /// <summary> 76 /// 清除缓存 77 /// </summary> 78 /// <returns></returns> 79 public bool RemoveCache() 80 { 81 return cachinger.Remove(CacheKey); 82 } 83 84 /// <summary> 85 /// 缓存键 86 /// </summary> 87 public struct CacheKeys 88 { 89 /// <summary> 90 /// Sys_User_List表的缓键名 91 /// </summary> 92 public const string KEY_DataTable_Sys_User_List = "Cache_WQB2_KEY_Sys_User_List"; 93 /// <summary> 94 /// SysDataArchive表的缓键名 95 /// </summary> 96 public static readonly string KEY_DataTable_SysDataArchive = "Cache_WQB2_KEY_SysDataArchive"; 97 /// <summary> 98 /// Sys_Area表的缓键名 99 /// </summary> 100 public static readonly string KEY_DataTable_Sys_Area = "Cache_WQB2_KEY_Sys_Area"; 101 /// <summary> 102 /// ProductSku表的缓键名 103 /// </summary> 104 public static readonly string KEY_DataTable_ProductSku = "Cache_WQB2_KEY_ProductSku"; 105 /// <summary> 106 /// Pro_Shux表的缓键名 107 /// </summary> 108 public static readonly string KEY_DataTable_Pro_Shux = "Cache_WQB2_KEY_Pro_Shux"; 109 /// <summary> 110 /// Pro_Class表的缓键名 111 /// </summary> 112 public static readonly string KEY_DataTable_Pro_Class = "Cache_WQB2_KEY_Pro_Class"; 113 /// <summary> 114 /// Pro_Brand表的缓键名 115 /// </summary> 116 public static readonly string KEY_DataTable_Pro_Brand = "Cache_WQB2_KEY_Pro_Brand"; 117 /// <summary> 118 /// Fxs_eShop_List表的缓键名 119 /// </summary> 120 public static readonly string KEY_DataTable_Fxs_eShop_List = "Cache_WQB2_KEY_Fxs_eShop_List"; 121 /// <summary> 122 /// Express_Type_Area表的缓键名 123 /// </summary> 124 public static readonly string KEY_DataTable_Express_Type_Area = "Cache_WQB2_KEY_Express_Type_Area"; 125 /// <summary> 126 /// Cux_Package_Pro_List表的缓键名 127 /// </summary> 128 public static readonly string KEY_DataTable_Cux_Package_Pro_List = "Cache_WQB2_KEY_Cux_Package_Pro_List"; 129 /// <summary> 130 /// Express_List表的缓键名 131 /// </summary> 132 public const string KEY_DataTable_Express_List = "Cache_WQB2_KEY_Express_List"; 133 /// <summary> 134 /// Express_Type表的缓键名 135 /// </summary> 136 public const string KEY_DataTable_Express_Type = "Cache_WQB2_KEY_Express_Type"; 137 /// <summary> 138 /// Sys_Para_Set表的缓键名 139 /// </summary> 140 public const string KEY_DataTable_Sys_Para_Set = "Cache_WQB2_KEY_Sys_Para_Set"; 141 /// <summary> 142 /// Sys_Para_Set表的缓键名 143 /// </summary> 144 public const string KEY_DataTable_Sys_Para_Set_OuterSystem = "Cache_WQB2_KEY_Sys_Para_Set_OuterSystem"; 145 /// <summary> 146 /// 商品原产地的缓键名 147 /// </summary> 148 public const string KEY_DataTable_Pro_Origin = "Cache_WQB2_KEY_Pro_Origin"; 149 /// <summary> 150 /// Sys_Para_Set表的缓键名 151 /// </summary> 152 public const string KEY_DataTable_Sys_Para_Set_ZyFxsOrderFenPeiCkSet = "Cache_WQB2_KEY_Sys_Para_Set_ZyFxsOrderFenPeiCkSet"; 153 /// <summary> 154 /// 库存隐藏设置详细 155 /// </summary> 156 public const string KEY_DataTable_Pro_Kuc_Set = "Cache_WQB2_Key_Pro_Kuc_Set"; 157 /// <summary> 158 /// 库存隐藏设置是否开启 159 /// </summary> 160 public const string KEY_DataTable_Sys_Para_Set_Pro_Kuc_Set_On = "Cache_WQB2_KEY_Sys_Para_Set_Pro_Kuc_Set_On"; 161 } 162 } 163 }
4.创建一个缓存管理对象CachingManager
1 using System; 2 using System.Configuration; 3 using System.IO; 4 using System.Net.Mime; 5 using System.Web; 6 using WQB.AppConfig; 7 8 namespace WQB.Caching 9 { 10 /// <summary> 11 /// Creates cachinger based on the current configuration. 12 /// </summary> 13 public static class CachingManager 14 { 15 private static ICachingFactory factory; 16 17 static CachingManager() 18 { 19 bool isMemcached = SiteConfig.IsMemcached(); 20 if (isMemcached) 21 { 22 factory = new MemcachingFactory(); 23 } 24 else 25 { 26 factory = new WebCachingFactory(); 27 } 28 } 29 30 /// <summary> 31 /// Assigns a new cacher factory programmatically. 32 /// </summary> 33 /// <param name="factory"></param> 34 public static void AssignFactory(ICachingFactory factory) 35 { 36 if (factory == null) throw new ArgumentNullException("factory"); 37 CachingManager.factory = factory; 38 } 39 40 /// <summary> 41 /// Returns a Cachingger with the specified name. 42 /// </summary> 43 /// <param name="name"></param> 44 /// <returns></returns> 45 public static ICaching GetCachingger() 46 { 47 return factory.GetCachingger(); 48 } 49 } 50 }
5.创建一个缓存工厂接口ICachingFactory
1 using System; 2 3 namespace WQB.Caching 4 { 5 /// <summary> 6 /// Implement this interface to instantiate your custom ICaching implementation 7 /// </summary> 8 public interface ICachingFactory 9 { 10 ICaching GetCachingger(); 11 } 12 }
6.创建一个Memcache缓存工厂MemcachingFactory
1 using System; 2 using Enyim.Caching; 3 4 namespace WQB.Caching 5 { 6 /// <summary> 7 /// Memcached Caching factory 8 /// </summary> 9 public class MemcachingFactory : ICachingFactory 10 { 11 ICaching ICachingFactory.GetCachingger() 12 { 13 return new MemcachingWrapper(); 14 } 15 } 16 }
7.创建一个系统缓存工厂WebCachingFactory
1 using System; 2 3 namespace WQB.Caching 4 { 5 /// <summary> 6 /// Caching factory 7 /// </summary> 8 public class WebCachingFactory : ICachingFactory 9 { 10 ICaching ICachingFactory.GetCachingger() 11 { 12 return new WebCachingWrapper(); 13 } 14 } 15 }
8.创建一个Memcache缓存类MemcachingWrapper
1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Net; 5 using System.Web.Configuration; 6 using Enyim.Caching; 7 using Enyim.Caching.Configuration; 8 using Enyim.Caching.Memcached; 9 using WQB.AppConfig; 10 11 namespace WQB.Caching 12 { 13 public class MemcachingWrapper : ICaching 14 { 15 private static MemcachedClient MemClient; 16 static readonly object padlock = new object(); 17 private static string CachePrefix = "";//本系统缓存前缀 用于保证多个系统的缓存唯一,可以用域名做为前缀 18 19 //线程安全的单例模式 20 public MemcachingWrapper() 21 { 22 lock (padlock) 23 { 24 if (MemClient == null) 25 { 26 MemcachedClientConfiguration memConfig = GetMemcachedClientConfiguration(); 27 MemClient = new MemcachedClient(memConfig); 28 } 29 } 30 } 31 32 public static MemcachedClientConfiguration GetMemcachedClientConfiguration() 33 { 34 MemcachedClientConfiguration memConfig = new MemcachedClientConfiguration(); 35 MemcachedConfig.MemcachedConfigInfo info = MemcachedConfig.GetMemcachedConfigInfo(); 36 memConfig.Servers.Clear(); 37 //m.ocs.aliyuncs.com是OCS控制台上的“内网地址”,OCS只有阿里云内网IP才能访问,所以需要先去获取内网IP 38 foreach (var item in info.Servers) 39 { 40 string ip = DataValidate.IsIP(item.Address) ? item.Address : Dns.GetHostEntry(item.Address).AddressList[0].ToString(); 41 IPAddress newaddress = IPAddress.Parse(ip); 42 IPEndPoint ipEndPoint = new IPEndPoint(newaddress, item.Port); 43 // 配置文件 - ip 44 memConfig.Servers.Add(ipEndPoint); 45 } 46 // 配置文件 - 协议 47 memConfig.Protocol = (MemcachedProtocol)info.Protocol; 48 if (!string.IsNullOrEmpty(info.UserName) && !string.IsNullOrEmpty(info.PassWord)) 49 { 50 // 配置文件 - 权限 51 memConfig.Authentication.Type = typeof(PlainTextAuthenticator); 52 memConfig.Authentication.Parameters["zone"] = info.Zone; 53 memConfig.Authentication.Parameters["userName"] = info.UserName; 54 memConfig.Authentication.Parameters["password"] = info.PassWord; 55 } 56 //配置文件 - 最大和最小连接数 57 memConfig.SocketPool.MinPoolSize = info.MinPoolSize; 58 memConfig.SocketPool.MaxPoolSize = info.MaxPoolSize; 59 //配置文件 - 连接超时时间和连接过期时间 60 memConfig.SocketPool.ConnectionTimeout = TimeSpan.Parse(info.ConnectionTimeout); 61 memConfig.SocketPool.DeadTimeout = TimeSpan.Parse(info.DeadTimeout); 62 CachePrefix = info.CachePrefix; 63 return memConfig; 64 } 65 66 /// <summary> 67 /// 删除缓存中所有的数据(会让Memcached服务端缓存池中的数据失效) 68 /// </summary> 69 /// <returns></returns> 70 public bool Clear() 71 { 72 //FlushAll方法只是让缓存失效,无法通过Get方法去获取了,但是不会从缓存中清除 73 MemClient.FlushAll(); 74 return true; 75 } 76 77 /// <summary> 78 /// 根据key值获取缓存 79 /// </summary> 80 /// <returns></returns> 81 public object Get(string key) 82 { 83 return MemClient.Get(CachePrefix + key); 84 } 85 86 /// <summary> 87 /// 根据key值和类型获取具体类型的缓存,Key不存在返回default(T) 88 /// </summary> 89 /// <returns></returns> 90 public T Get<T>(string key) 91 { 92 return MemClient.Get<T>(CachePrefix + key); 93 } 94 95 /// <summary> 96 /// 添加缓存,过期时间默认为5个小时 97 /// </summary> 98 /// <returns></returns> 99 public bool Insert(string key, object obj) 100 { 101 return MemClient.Store(StoreMode.Set, CachePrefix + key, obj); 102 } 103 /// <summary> 104 /// 添加缓存,同时设置缓存过期时间 105 /// 使用过期时间后无效,暂时先用永久有效的方法 106 /// </summary> 107 /// <param name="key"></param> 108 /// <param name="obj"></param> 109 /// <param name="expiredSeconds">缓存过期时间,单位秒</param> 110 /// <returns></returns> 111 public bool Insert(string key, object obj, int expiredSeconds) 112 { 113 bool re = MemClient.Store(StoreMode.Set, CachePrefix + key, obj, DateTime.Now.AddSeconds(expiredSeconds)); 114 if (!re)//使用过期时间后无效,再用永久有效的方法;有些服务器可能不支持缓存过期 115 { 116 re = MemClient.Store(StoreMode.Set, CachePrefix + key, obj); 117 } 118 return re; 119 } 120 121 /// <summary> 122 /// 根据key值删除缓存,Key不存在返回false 123 /// </summary> 124 /// <returns></returns> 125 public bool Remove(string key) 126 { 127 return MemClient.Remove(CachePrefix + key); 128 } 129 } 130 }
9.创建一个系统缓存类WebCachingWrapper
1 using System; 2 using System.Collections; 3 using System.Web; 4 using System.Web.Caching; 5 6 namespace WQB.Caching 7 { 8 internal class WebCachingWrapper : ICaching 9 { 10 private static readonly Cache _Cache = InitSysCache(); 11 12 /// <summary> 13 /// 从HttpContext中获取缓存 14 /// </summary> 15 private static Cache InitSysCache() 16 { 17 HttpContext current = HttpContext.Current; 18 if (current != null) 19 { 20 return current.Cache; 21 } 22 return HttpRuntime.Cache; 23 } 24 25 /// <summary> 26 /// 删除所有的缓存 27 /// </summary> 28 /// <returns></returns> 29 public bool Clear() 30 { 31 IDictionaryEnumerator enumerator = _Cache.GetEnumerator(); 32 ArrayList list = new ArrayList(); 33 while (enumerator.MoveNext()) 34 { 35 list.Add(enumerator.Key); 36 } 37 foreach (string str in list) 38 { 39 _Cache.Remove(str); 40 } 41 return true; 42 } 43 44 /// <summary> 45 /// 根据key值获取缓存 46 /// </summary> 47 /// <returns></returns> 48 public object Get(string key) 49 { 50 return _Cache[key]; 51 } 52 53 /// <summary> 54 /// 根据key值和类型获取具体类型的缓存 55 /// </summary> 56 /// <returns></returns> 57 public T Get<T>(string key) 58 { 59 try 60 { 61 return (T)_Cache[key]; 62 } 63 catch 64 { 65 return default(T); 66 } 67 } 68 69 /// <summary> 70 /// 添加缓存,过期时间默认为5个小时 71 /// </summary> 72 /// <returns></returns> 73 public bool Insert(string key, object obj) 74 { 75 Insert(key, obj, 3600 * 5); 76 return true; 77 } 78 79 /// <summary> 80 /// 添加缓存,同时设置缓存过期时间 81 /// </summary> 82 /// <param name="key"></param> 83 /// <param name="obj"></param> 84 /// <param name="expiredSeconds">缓存过期时间,单位秒</param> 85 /// <returns></returns> 86 public bool Insert(string key, object obj, int expiredSeconds) 87 { 88 try 89 { 90 if (obj != null) 91 { 92 _Cache.Insert(key, obj, null, DateTime.Now.AddSeconds(expiredSeconds), TimeSpan.Zero, CacheItemPriority.NotRemovable, null); 93 } 94 return true; 95 96 } 97 catch (Exception) 98 { 99 100 return false; 101 } 102 } 103 104 /// <summary> 105 /// 根据key值删除缓存 106 /// </summary> 107 /// <returns></returns> 108 public bool Remove(string key) 109 { 110 object obj = _Cache.Remove(key); 111 return obj != null; 112 } 113 } 114 }
以上是关于缓存管理的主要内容,如果未能解决你的问题,请参考以下文章
Swift新async/await并发中利用Task防止指定代码片段执行的数据竞争(Data Race)问题