沉默的小泷包 發表於 2019-9-23 00:18:00

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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 字典</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">object</span>&gt; _dataDic = <span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">object</span>&gt;();


      <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 定义一个静态变量来保存类的实例</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 定义一个标识确保线程同步</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 单例</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;返回类型为Session&lt;/returns&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 删除成员</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="name"&gt;&lt;/param&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 删除全部成员</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 本类的索引器</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;返回Object成员&lt;/returns&gt;</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&lt;<span style="color: rgba(0, 0, 255, 1)">object</span>&gt; _asyncLocalConnectionOject = <span style="color: rgba(0, 0, 255, 1)">new</span> AsyncLocal&lt;<span style="color: rgba(0, 0, 255, 1)">object</span>&gt;();

      <span style="color: rgba(128, 128, 128, 1)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 设置共享数据库连接</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="obj"&gt;&lt;/param&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 获取共享数据库连接</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 清空共享数据库连接</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 获取缓存的值</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="key"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 移除缓存</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="key"&gt;&lt;/param&gt;</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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 设置缓存</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="key"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="value"&gt;&lt;/param&gt;</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 =&gt;
            {
                <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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 设置缓存(固定时间过期)</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="key"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="value"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="absoluteExpiration"&gt;&lt;/param&gt;</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 =&gt;
            {

                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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 设置缓存(滚动时间过期)</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="key"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="value"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="slidingExpiration"&gt;&lt;/param&gt;</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 =&gt;
            {

                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)">/// &lt;summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// 文件依赖缓存</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;/summary&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="key"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;param name="fullName"&gt;&lt;/param&gt;</span>
      <span style="color: rgba(128, 128, 128, 1)">/// &lt;returns&gt;&lt;/returns&gt;</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 =&gt;
            {
                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">
&nbsp;&nbsp;&nbsp;&nbsp;如果您觉得阅读本文对您有帮助,请点一下右下角推荐”按钮,博主在此感谢!另外您也可以选择【<strong>关注我</strong>】,可以很方便找到我!</label><br>
&nbsp;&nbsp;&nbsp;&nbsp;感谢您花时间阅读此篇文章,如果您觉得看了这篇文章之后心情还比较高兴,可以打赏一下,请博主喝上一杯咖啡,让博主继续码字……<br>
&nbsp;&nbsp;&nbsp;&nbsp;本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/snailblog 欢迎各位转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
</div><br><br>
来源:https://www.cnblogs.com/snailblog/p/11570094.html
頁: [1]
查看完整版本: C# 缓存的实现