C# 缓存的实现

  • 2019 年 10 月 3 日
  • 笔记

缓存的实现

我们不是做第三方比如Redis等的缓存实现,而是根据实际情况,基于C#上做一些环境变量的保存,方便项目使用。

1、系统全局变量

很多时候,在系统运行开始,需要对系统的运行参数进行保存,以便供全局使用。

代码如下:

 public class PFTCacheObject      {          /// <summary>          /// 字典          /// </summary>          private static Dictionary<string, object> _dataDic = new Dictionary<string, object>();              /// <summary>          /// 定义一个静态变量来保存类的实例          /// </summary>          private static PFTCacheObject _session;            /// <summary>          /// 定义一个标识确保线程同步          /// </summary>          private static readonly object _locker = new object();              /// <summary>          /// 单例          /// </summary>          /// <returns>返回类型为Session</returns>          public static PFTCacheObject Instance          {              get              {                  if (_session == null)                  {                      lock (_locker)                      {                          if (_session == null)// 如果类的实例不存在则创建,否则直接返回                          {                              _session = new PFTCacheObject();                          }                      }                  }                  return _session;              }          }            #region Remove 移除            /// <summary>          /// 删除成员          /// </summary>          /// <param name="name"></param>          public void Remove(string name)          {              _dataDic.Remove(name);          }            /// <summary>          /// 删除全部成员          /// </summary>          public void RemoveAll()          {              _dataDic.Clear();          }          #endregion            #region 本类的索引器            /// <summary>          /// 本类的索引器          /// </summary>          /// <returns>返回Object成员</returns>          public Object this[string index]          {              get              {                  if (_dataDic.ContainsKey(index))                  {                      Object obj = (Object)_dataDic[index];                      return obj;                  }                  return null;              }              set              {                  if (_dataDic.ContainsKey(index))                  {                      _dataDic.Remove(index);                  }                  _dataDic.Add(index, value);              }          }          #endregion          }

这里使用一个静态变量的Dictionary来进行保存,所有项目均可以直接获取。

2、异步的数据缓存

在web上面,很多时候都是使用的HttpContext.Current.Items进行数据缓存,在.Net Framework框架上使用CallContext.LogicalSetData。在.Net Standard 上面CallContext.LogicalSetData已经不能使用了,替换他的方法是AsyncLocal。因为我们现在都是使用的是.Net Standard,并且我们项目并不仅仅是web,所以这里我们就只用使用AsyncLocal实现。

代码如下

public class PFTCallContext      {            #region  共享数据库连接            private static AsyncLocal<object> _asyncLocalConnectionOject = new AsyncLocal<object>();            /// <summary>          /// 设置共享数据库连接          /// </summary>          /// <param name="obj"></param>          public static void SetConnectionOject(object obj)          {              _asyncLocalConnectionOject.Value = obj;          }            /// <summary>          /// 获取共享数据库连接          /// </summary>          /// <returns></returns>          public static object GetConnectionOject()          {              return _asyncLocalConnectionOject.Value;          }            /// <summary>          /// 清空共享数据库连接          /// </summary>          public static void ClearConnectionOject()          {              _asyncLocalConnectionOject.Value = null;          }            #endregion            }

这里我们就先定义一个当前数据库连接对象的缓存。如果还需要其他的定义,你可以直接实现。

3、.Net Core 的MemoryCache

本来这块想使用.Net Framework框架中的cache的,但是.Net Core才是未来的大势,而且.Net Framework的cache已经有很多的实现方法了,所以这里我就直接用.Net Core 的MemoryCache。.Net Core蜗牛也在学习中,相关的API也在不断的研究,如果有问题,请大家帮忙纠正。

public static class PFTCache      {          public readonly static IMemoryCache _memoryCache;            static PFTCache()          {              _memoryCache = new MemoryCache(Options.Create(new MemoryCacheOptions()));          }            #region 常规缓存          /// <summary>          /// 获取缓存的值          /// </summary>          /// <param name="key"></param>          /// <returns></returns>          public static Object GetCache(string key)          {              return _memoryCache.Get(key);          }          /// <summary>          /// 移除缓存          /// </summary>          /// <param name="key"></param>          public static void Remove(string key)          {              _memoryCache.Remove(key);          }          /// <summary>          /// 设置缓存          /// </summary>          /// <param name="key"></param>          /// <param name="value"></param>          public static void SetCache(string key, Object value)          {              _memoryCache.GetOrCreate(key, entry =>              {                  return value;              });          }          /// <summary>          /// 设置缓存(固定时间过期)          /// </summary>          /// <param name="key"></param>          /// <param name="value"></param>          /// <param name="absoluteExpiration"></param>          public static void SetCacheAbsolute(string key, Object value, int absoluteExpiration)          {              _memoryCache.GetOrCreate(key, entry =>              {                    entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(absoluteExpiration));                  return value;              });          }          /// <summary>          /// 设置缓存(滚动时间过期)          /// </summary>          /// <param name="key"></param>          /// <param name="value"></param>          /// <param name="slidingExpiration"></param>          public static void SetCacheSliding(string key, Object value, int slidingExpiration)          {              _memoryCache.GetOrCreate(key, entry =>              {                    entry.SetSlidingExpiration(TimeSpan.FromSeconds(slidingExpiration));                  return value;              });          }            #endregion            #region 文件依赖缓存          /// <summary>          /// 文件依赖缓存          /// </summary>          /// <param name="key"></param>          /// <param name="fullName"></param>          /// <returns></returns>          public static string DependentCacheFile(string key, string fullName)          {              var basePath = PFTFile.GetDirectoryName(fullName);              var fileName = PFTFile.GetFileName(fullName);              var fileProvider = new PhysicalFileProvider(basePath);              return _memoryCache.GetOrCreate(key, entry =>              {                  entry.AddExpirationToken(fileProvider.Watch(fileName));                  return PFTFile.IsExistFile(fullName) ? PFTFile.ReadFile(fullName) : string.Empty;              });          }          #endregion        }

好了,关于缓存这块蜗牛就先说到这里。