Cache 是什么?
- Cache即高速缓存
- Cache是分配在服务器上的一个公共内存片(Cache越多,占用的内存资源也就越多)
- Cache可以存放任何对象
- Cache 是有时间限制的,超过了服务器设定的过期时间,就会被服务器回收
为什么要使用Cache?
- 降低延迟,使响应速度加快
- 降低网络传输,使响应速度加快
什么时候用Cache?
- Cache一般用在数据较固定,使用比较频繁的地方(这样在很大程度上减少了用户与数据库的交互,提高了系统的性能)
在web开发中会经常使用到缓存对象(Cache),在asp.net中提供了两种缓存对象
- HttpContext.Current.Cache 为HTTP请求获取Cache对象,由于此缓存封装在了HttpContext中,而HttpContext只局限于Web中,所以此缓存信息只能在web中使用。
- HttpRuntime.Cache 获取当前应用程序的Cache,此缓存信息虽然被放在了System.Web命名空间下,但是分Web程序也可以使用此缓存。
下面整理了HttpRuntime.Cache的一些公用类
public class RedisCache
{
//定义一个静态变量Redis存放 RedisCach 的实例
private static RedisCache Redis;
//定义一个标识确保线程同步
private static readonly object locker = new object();
//定义一个静态变量存放服务端配置的地址
private static string _conn = ConfigurationManager.AppSettings["RedisAddress"] ?? "127.0.0.1:6379";
//定义公有构造函数,使外界可以访问RedisCache的实例
public RedisCache()
{
}
//定义一个公有方法提供一个全局访问点,
public static RedisCache GetClient()
{
try
{
//当第一个线程运行到这里时,此时会对locker对象“加锁”
//当第二个线程运行该方法时,首先会检测到locker对象为加锁状态,该线程就会挂起,等待第一个线程解锁
//lock语句运行完后(即线程运行完之后),会对该对象解锁
lock (locker)
{
//如果类的实例不存在则创建,否则直接返回
if (Redis == null)
{
Redis = new RedisCache();
}
}
}
catch (Exception ex)
{
WebApiLog.Exception("", "", "RedisCache初始化错误!" + ex.Message);
}
return Redis;
}
public T Get<T>(string key) where T : class
{
using (var client = ConnectionMultiplexer.Connect(_conn))
{
var strValue = client.GetDatabase().StringGet(key);
return string.IsNullOrEmpty(strValue) ? null : JsonHelper.GetTFromJsonString<T>(strValue);
}
}
public void Insert(string key, object obj)
{
using (var client = ConnectionMultiplexer.Connect(_conn))
{
var value = JsonHelper.GetJsonFromObject(obj);
client.GetDatabase().StringSet(key, value);
}
}
public void Insert(string key, object obj, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemUpdateCallback onUpdateCallback=null)
{
if (obj == null)
return;
var value = JsonHelper.GetJsonFromObject(obj);
using (var client = ConnectionMultiplexer.Connect(_conn))
{
if (slidingExpiration != new TimeSpan())
client.GetDatabase().StringSet(key, value, slidingExpiration);
else if (absoluteExpiration!=DateTime.MinValue)
{
client.GetDatabase().StringSet(key, value, absoluteExpiration-DateTime.Now);
}
else
{
client.GetDatabase().StringSet(key, value);
}
}
}
public void Remove(string key)
{
using (var client = ConnectionMultiplexer.Connect(_conn))
{
client.GetDatabase().KeyDelete(key);
}
}
}
public class CommonCache
{
private static RedisCache cache = RedisCache.GetClient();
/// <summary>
/// 获取缓存对象
/// </summary>
public static T Get<T>(string key) where T : class
{
if (string.IsNullOrWhiteSpace(key)) return null;
T t = default(T);
var q = cache.Get<T>(key);
if (q != null)
{
t = q as T;
}
return t;
}
/// <summary>
/// 移除缓存对象
/// </summary>
public static void Remove(string key)
{
cache.Remove(key);
}
/// <summary>
/// s设置缓存对象
/// </summary>
public static int Add(string key, object value)
{
if(value!=null)
cache.Insert(key, value);
return 1;
}
/// <summary>
/// 设置缓存对象
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="span">停止访问后多久失效</param>
/// <returns></returns>
public static int Add(string key, object value,TimeSpan span)
{
Add(key, value,span,1);
return 1;
}
/// <summary>
/// 设置缓存对象
/// </summary>
public static int Add(string key, object value, TimeSpan span, int cachetype = 1, System.Web.Caching.CacheItemUpdateCallback callback = null)
{
if (cachetype == 1)
{
if (callback != null)
{
cache.Insert(key, value, null, DateTime.Now + span, System.Web.Caching.Cache.NoSlidingExpiration, callback);
}
else
{
cache.Insert(key, value, null, DateTime.Now + span, System.Web.Caching.Cache.NoSlidingExpiration);
}
}
else
{
if (callback != null)
{
cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, span, callback);
}
else
{
cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, span);
}
}
return 0;
}
}