微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C# 内存缓存工具类 MemoryCacheUtil

C# 内存缓存工具类 MemoryCacheUtil

using System;
 System.Collections.Concurrent;
 System.Collections.Generic;
 System.Linq;
 System.Security.Cryptography;
 System.Text;
 System.Threading.Tasks;
 System.Timers;

namespace Utils
{
    /// <summary>
    /// 缓存
     缓存数据存储在内存中
     适用于CS项目,BS项目慎用
    </summary>
    public static class MemoryCacheUtil
    {
        #region 变量
        <summary>
         内存缓存
        </summary>
        private static ConcurrentDictionary<string,CacheData> _cacheDict = new ConcurrentDictionary<();

         对不同的键提供不同的锁,用于读缓存
        string> _dictLocksForReadCache = string> 过期缓存检测Timer
        static Timer _timerCheckCache;
        #endregion

        #region 静态构造函数
         MemoryCacheUtil()
        {
            _timerCheckCache = new Timer();
            _timerCheckCache.Interval = 60 * 1000;
            _timerCheckCache.Elapsed += _timerCheckCache_Elapsed;
            _timerCheckCache.Start();
        }
        #region 获取并缓存数据
         获取并缓存数据
         高并发的情况建议使用此重载函数,防止重复写入内存缓存
        </summary>
        <param name="cacheKey"></param>
        <param name="func">在此方法中初始化数据<param name="expirationSeconds">缓存过期时间(秒),0表示永不过期<param name="refreshCache">立即刷新缓存</param>
        static T TryGetValue<T>(string cacheKey,Func<T> func,1)">int expirationSeconds = 0,1)">bool refreshCache = false)
        {
            lock (_dictLocksForReadCache.GetorAdd(cacheKey,cacheKey))
            {
                object cacheValue = MemoryCacheUtil.GetValue(cacheKey);
                if (cacheValue != null && !refreshCache)
                {
                    return (T)cacheValue;
                }
                else
                {
                    T value = func();
                    MemoryCacheUtil.SetValue(cacheKey,value,expirationSeconds);
                     value;
                }
            }
        }
        #region SetValue 保存键值对
         保存键值对
        <param name="key">缓存键<param name="value">过期时间(秒),0表示永不过期internal void SetValue(string key,1)">object value,1)">0try
            {
                CacheData data =  CacheData(key,value);
                data.updateTime = DateTime.Now;
                data.expirationSeconds = expirationSeconds;

                CacheData temp;
                _cacheDict.TryRemove(key,out temp);
                _cacheDict.TryAdd(key,data);
            }
            catch (Exception ex)
            {
                LogUtil.Error(ex,"MemoryCacheUtil写缓存错误");
            }
        }
        #region GetValue 获取键值对
         获取键值对
        object GetValue(string key)
        {
            
            {
                CacheData data;
                if (_cacheDict.TryGetValue(key,1)"> data))
                {
                    if (data.expirationSeconds > 0 && DateTime.Now.Subtract(data.updateTime).TotalSeconds > data.expirationSeconds)
                    {
                        CacheData temp;
                        _cacheDict.TryRemove(key,1)"> temp);
                        return null;
                    }
                     data.value;
                }
                ;
            }
            MemoryCacheUtil读缓存错误);
                ;
            }
        }
        #region Delete 删除缓存
         删除缓存
        void Delete( key)
        {
            CacheData temp;
            _cacheDict.TryRemove(key,1)"> temp);
        }
        #region Deleteall 删除全部缓存
         删除全部缓存
        void Deleteall()
        {
            _cacheDict.Clear();
        }
        #region 过期缓存检测
         过期缓存检测
        void _timerCheckCache_Elapsed(object sender,System.Timers.ElapsedEventArgs e)
        {
            Task.Run(() =>
            {
                
                {
                    foreach (string cacheKey in _cacheDict.Keys.ToList())
                    {
                        CacheData data;
                        if (_cacheDict.TryGetValue(cacheKey,1)"> data))
                        {
                             data.expirationSeconds)
                            {
                                CacheData temp;
                                 strTemp;
                                _cacheDict.TryRemove(cacheKey,1)"> temp);
                                _dictLocksForReadCache.TryRemove(cacheKey,1)"> strTemp);
                            }
                        }
                    }
                }
                 (Exception ex)
                {
                    LogUtil.Error(ex,1)">过期缓存检测出错);
                }
            });
        }
        #endregion

    }
}
View Code

为什么BS项目慎用?因为IIS会回收进程,所以需要注意一下。

为什么过期缓存检测遍历代码是foreach (string cacheKey in _cacheDict.Keys.ToList()),要使用ToList()?_cacheDict.Keys不是线程安全的,防止并发异常。

为什么加锁的代码是lock (_dictLocksForReadCache.GetorAdd(cacheKey,cacheKey))?为了支持多线程并发,防止重复进入func函数

CacheData类:

<summary>
 缓存数据
</summary>
[Serializable]
 CacheData
{
    string key { get; set; }
    object value {  缓存更新时间
    public DateTime updateTime {  过期时间(秒),0表示永不过期
    int expirationSeconds { ; }

     缓存数据
    </summary>
    </param>
    </param>
    public CacheData( value)
    {
        this.key = key;
        this.value = value;
    }
}
View Code

如何使用:

void button2_Click(string> list = MemoryCacheUtil.TryGetValue<List<string>>(cacheKey001",() =>
    {
         QueryData();
    });
}

 模拟从数据库查询数据
private List< QueryData()
{
    List<string> result = new List<();

    for (int i = 0; i < 10; i++)
    {
        result.Add(i.ToString());
    }

     result;
}
View Code

 多线程并发测试:

 TestMemoryCache()
{
    Log(开始);
    5; i++)
    {
        Task.Run(() =>
        {
            string str1 = MemoryCacheUtil.TryGetValue<string>(1
            {
                Thread.Sleep(2000);
                Log(取数据1return ;
            });
            Log(str1);
        });

        Task.Run(() =>string str2 = MemoryCacheUtil.TryGetValue<2取数据2;
            });
            Log(str2);
        });

        Task.Run(() =>string str3 = MemoryCacheUtil.TryGetValue<3取数据3;
            });
            Log(str3);
        });
    }
}
View Code

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐