C# 缓存的实现
<h2>缓存的实现</h2><p>我们不是做第三方比如Redis等的缓存实现,而是根据实际情况,基于C#上做一些环境变量的保存,方便项目使用。</p>
<h3>1、系统全局变量</h3>
<p>很多时候,在系统运行开始,需要对系统的运行参数进行保存,以便供全局使用。</p>
<p>代码如下:</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> PFTCacheObject
{
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 字典</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Dictionary<<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">object</span>> _dataDic = <span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary<<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">object</span>>();
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 定义一个静态变量来保存类的实例</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> PFTCacheObject _session;
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 定义一个标识确保线程同步</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">object</span> _locker = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">object</span>();
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 单例</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <returns>返回类型为Session</returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> PFTCacheObject Instance
{
<span style="color: rgba(0, 0, 255, 1)">get</span>
{
<span style="color: rgba(0, 0, 255, 1)">if</span> (_session == <span style="color: rgba(0, 0, 255, 1)">null</span>)
{
<span style="color: rgba(0, 0, 255, 1)">lock</span> (_locker)
{
<span style="color: rgba(0, 0, 255, 1)">if</span> (_session == <span style="color: rgba(0, 0, 255, 1)">null</span>)<span style="color: rgba(0, 128, 0, 1)">// 如果类的实例不存在则创建,否则直接返回</span>
{
_session = <span style="color: rgba(0, 0, 255, 1)">new</span> PFTCacheObject();
}
}
}
<span style="color: rgba(0, 0, 255, 1)">return</span> _session;
}
}
#region Remove 移除
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 删除成员</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="name"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Remove(<span style="color: rgba(0, 0, 255, 1)">string</span> name)
{
_dataDic.Remove(name);
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 删除全部成员</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> RemoveAll()
{
_dataDic.Clear();
}
#endregion
#region 本类的索引器
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 本类的索引器</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <returns>返回Object成员</returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> Object <span style="color: rgba(0, 0, 255, 1)">this</span>[<span style="color: rgba(0, 0, 255, 1)">string</span> index]
{
<span style="color: rgba(0, 0, 255, 1)">get</span>
{
<span style="color: rgba(0, 0, 255, 1)">if</span> (_dataDic.ContainsKey(index))
{
Object obj = (Object)_dataDic;
<span style="color: rgba(0, 0, 255, 1)">return</span> obj;
}
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span>;
}
<span style="color: rgba(0, 0, 255, 1)">set</span>
{
<span style="color: rgba(0, 0, 255, 1)">if</span> (_dataDic.ContainsKey(index))
{
_dataDic.Remove(index);
}
_dataDic.Add(index, <span style="color: rgba(0, 0, 255, 1)">value</span>);
}
}
#endregion
}</pre>
</div>
<p>这里使用一个静态变量的Dictionary来进行保存,所有项目均可以直接获取。</p>
<h3>2、异步的数据缓存</h3>
<p>在web上面,很多时候都是使用的HttpContext.Current.Items进行数据缓存,在.Net Framework框架上使用CallContext.LogicalSetData。在.Net Standard 上面CallContext.LogicalSetData已经不能使用了,替换他的方法是AsyncLocal。因为我们现在都是使用的是.Net Standard,并且我们项目并不仅仅是web,所以这里我们就只用使用AsyncLocal实现。</p>
<p>代码如下</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> PFTCallContext
{
#region共享数据库连接
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> AsyncLocal<<span style="color: rgba(0, 0, 255, 1)">object</span>> _asyncLocalConnectionOject = <span style="color: rgba(0, 0, 255, 1)">new</span> AsyncLocal<<span style="color: rgba(0, 0, 255, 1)">object</span>>();
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 设置共享数据库连接</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="obj"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetConnectionOject(<span style="color: rgba(0, 0, 255, 1)">object</span> obj)
{
_asyncLocalConnectionOject.Value = obj;
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 获取共享数据库连接</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">object</span> GetConnectionOject()
{
<span style="color: rgba(0, 0, 255, 1)">return</span> _asyncLocalConnectionOject.Value;
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 清空共享数据库连接</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> ClearConnectionOject()
{
_asyncLocalConnectionOject.Value = <span style="color: rgba(0, 0, 255, 1)">null</span>;
}
#endregion
}</pre>
</div>
<p>这里我们就先定义一个当前数据库连接对象的缓存。如果还需要其他的定义,你可以直接实现。</p>
<h3>3、.Net Core 的MemoryCache</h3>
<p>本来这块想使用.Net Framework框架中的cache的,但是.Net Core才是未来的大势,而且.Net Framework的cache已经有很多的实现方法了,所以这里我就直接用.Net Core 的MemoryCache。.Net Core蜗牛也在学习中,相关的API也在不断的研究,如果有问题,请大家帮忙纠正。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">class</span> PFTCache
{
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">static</span> IMemoryCache _memoryCache;
<span style="color: rgba(0, 0, 255, 1)">static</span> PFTCache()
{
_memoryCache = <span style="color: rgba(0, 0, 255, 1)">new</span> MemoryCache(Options.Create(<span style="color: rgba(0, 0, 255, 1)">new</span> MemoryCacheOptions()));
}
#region 常规缓存
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 获取缓存的值</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="key"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Object GetCache(<span style="color: rgba(0, 0, 255, 1)">string</span> key)
{
<span style="color: rgba(0, 0, 255, 1)">return</span> _memoryCache.Get(key);
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 移除缓存</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="key"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Remove(<span style="color: rgba(0, 0, 255, 1)">string</span> key)
{
_memoryCache.Remove(key);
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 设置缓存</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="key"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="value"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetCache(<span style="color: rgba(0, 0, 255, 1)">string</span> key, Object <span style="color: rgba(0, 0, 255, 1)">value</span>)
{
_memoryCache.GetOrCreate(key, entry =>
{
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">value</span>;
});
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 设置缓存(固定时间过期)</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="key"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="value"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="absoluteExpiration"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetCacheAbsolute(<span style="color: rgba(0, 0, 255, 1)">string</span> key, Object <span style="color: rgba(0, 0, 255, 1)">value</span>, <span style="color: rgba(0, 0, 255, 1)">int</span> absoluteExpiration)
{
_memoryCache.GetOrCreate(key, entry =>
{
entry.SetAbsoluteExpiration(TimeSpan.FromSeconds(absoluteExpiration));
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">value</span>;
});
}
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 设置缓存(滚动时间过期)</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="key"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="value"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="slidingExpiration"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetCacheSliding(<span style="color: rgba(0, 0, 255, 1)">string</span> key, Object <span style="color: rgba(0, 0, 255, 1)">value</span>, <span style="color: rgba(0, 0, 255, 1)">int</span> slidingExpiration)
{
_memoryCache.GetOrCreate(key, entry =>
{
entry.SetSlidingExpiration(TimeSpan.FromSeconds(slidingExpiration));
<span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">value</span>;
});
}
#endregion
#region 文件依赖缓存
<span style="color: rgba(128, 128, 128, 1)">/// <summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// 文件依赖缓存</span>
<span style="color: rgba(128, 128, 128, 1)">/// </summary></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="key"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <param name="fullName"></param></span>
<span style="color: rgba(128, 128, 128, 1)">/// <returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span> DependentCacheFile(<span style="color: rgba(0, 0, 255, 1)">string</span> key, <span style="color: rgba(0, 0, 255, 1)">string</span> fullName)
{
var basePath = PFTFile.GetDirectoryName(fullName);
var fileName = PFTFile.GetFileName(fullName);
var fileProvider = <span style="color: rgba(0, 0, 255, 1)">new</span> PhysicalFileProvider(basePath);
<span style="color: rgba(0, 0, 255, 1)">return</span> _memoryCache.GetOrCreate(key, entry =>
{
entry.AddExpirationToken(fileProvider.Watch(fileName));
<span style="color: rgba(0, 0, 255, 1)">return</span> PFTFile.IsExistFile(fullName) ? PFTFile.ReadFile(fullName) : <span style="color: rgba(0, 0, 255, 1)">string</span>.Empty;
});
}
#endregion
}</pre>
</div>
<p>好了,关于缓存这块蜗牛就先说到这里。</p>
</div>
<div id="MySignature" role="contentinfo">
<div style="font-size: 13px; border: 1px dashed rgb(45, 161, 45); padding: 10px 15px; background-color: rgb(248, 248, 248)">
<label style="font-weight: bold">
如果您觉得阅读本文对您有帮助,请点一下右下角推荐”按钮,博主在此感谢!另外您也可以选择【<strong>关注我</strong>】,可以很方便找到我!</label><br>
感谢您花时间阅读此篇文章,如果您觉得看了这篇文章之后心情还比较高兴,可以打赏一下,请博主喝上一杯咖啡,让博主继续码字……<br>
本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/snailblog 欢迎各位转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
</div><br><br>
来源:https://www.cnblogs.com/snailblog/p/11570094.html
頁:
[1]