C#-缓存(一)_内存缓存MemoryCache

  代码地址:CSharp_DistributedCache_Simple

一、WinForm版(System.Runtime.Caching)

1、MemoryCache示例

2、引用Negut包

3、MemoryCacheHelper

查看代码
/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描    述:MemoryCache帮助类(使用示例)
*│ 作    者:执笔小白
*│ 版    本:1.0
*│ 创建时间:2023-7-17 22:02:56
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 命名空间: Util.MemoryCacheDome
*│ 类    名:MemoryCacheHelper
*└──────────────────────────────────────────────────────────────┘
*/
using System.Runtime.Caching;
using System.Collections.Specialized;

namespace Util.MemoryCacheDome
{
    /// <summary>
    /// MemoryCache帮助类(使用示例)
    /// </summary>
    public static class MemoryCacheHelper : object
    {
        /// <summary>
        /// 对象
        /// </summary>
        private static MemoryCache _cache;

        #region 创建与销毁MemoryCache
        /// <summary>
        /// 创建新MemoryCache-使用默认配置项
        /// 程序退出后缓存会被清空
        /// </summary>
        /// <param name="name">MemoryCache名称</param>
        /// <param name="config">值集合</param>
        /// <param name="ignoreConfigSection">忽略配置Section</param>
        /// <returns></returns>
        public static MemoryCache CreateMemoryCache()
        {
            _cache = MemoryCache.Default;  //声明缓存类
            return _cache;
        }

        /// <summary>
        /// 创建新MemoryCache-通过配置项
        /// </summary>
        /// <param name="name">MemoryCache名称</param>
        /// <param name="config">值集合</param>
        /// <param name="ignoreConfigSection">忽略配置Section</param>
        /// <returns></returns>
        public static MemoryCache NewMemoryCache(string name, NameValueCollection config, bool ignoreConfigSection) => _cache = new MemoryCache(name, config, ignoreConfigSection);

        /// <summary>
        /// 创建一个 CacheEntryChangeMonitor 对象,响应指定缓存项的更改事件
        /// </summary>
        /// <param name="keys">需要响应的缓存项的枚举</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static CacheEntryChangeMonitor CreateCacheEntryChangeMonitor(IEnumerable<string> keys, string regionName = null) => _cache.CreateCacheEntryChangeMonitor(keys, regionName);

        /// <summary>
        /// 销毁MemoryCache
        /// </summary>
        public static void Dispose() => _cache.Dispose();

        /// <summary>
        /// 从缓存对象中移除指定百分比的缓存项
        /// </summary>
        /// <param name="percent"></param>
        /// <returns></returns>
        public static long Trim(int percent) => _cache.Trim(percent);
        #endregion 创建与销毁MemoryCache

        #region 获取MemoryCache配置
        /// <summary>
        /// 获取计算机上缓存可使用的内存量(以字节为单位)
        /// </summary>
        public static long CacheMemoryLimit => _cache.CacheMemoryLimit;
        /// <summary>
        /// 获取计算机上缓存可使用的物理内存的百分比
        /// </summary>
        public static long PhysicalMemoryLimit => _cache.PhysicalMemoryLimit;

        /// <summary>
        /// 获取缓存提供的功能的说明
        /// </summary>
        public static DefaultCacheCapabilities DefaultCacheCapabilities => _cache.DefaultCacheCapabilities;

        /// <summary>
        /// 获取在缓存更新其内存统计信息之前需等待的最大时间量
        /// </summary>
        public static TimeSpan PollingInterval => _cache.PollingInterval;

        /// <summary>
        /// 获取缓存的名称
        /// </summary>
        public static string Name => _cache.Name;
        #endregion 获取MemoryCache配置

        #region 存、取、删除值,检查是否存在值
        /// <summary>
        /// 确定缓存中是否存在某个缓存项
        /// </summary>
        /// <param name="key">要搜索的缓存项的唯一标识符</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static bool Contains(string key, string regionName = null) => _cache.Contains(key, regionName);

        #region 存值-复写原值
        /// <summary>
        /// 使用键和值将某个缓存项插入缓存中,并指定过期时间
        /// </summary>
        /// <param name="key">要插入的缓存项的唯一标识符</param>
        /// <param name="value">该缓存项的数据</param>
        /// <param name="absoluteExpiration">缓存项的固定的过期日期和时间</param>
        /// <param name="regionName">某个缓存集合</param>
        public static void Set(string key, object value, DateTimeOffset absoluteExpiration, string regionName = null) => _cache.Set(key, value, absoluteExpiration, regionName);

        /// <summary>
        /// 使用键和值将某个缓存项插入缓存中,并指定逐出选项(代替过期时间)
        /// </summary>
        /// <param name="key">要插入的缓存项的唯一标识符</param>
        /// <param name="value">该缓存项的数据</param>
        /// <param name="policy">一个包含该缓存项的逐出详细信息的对象。 此对象提供比简单绝对过期更多的逐出选项</param>
        /// <param name="regionName">某个缓存集合</param>
        public static void Set(string key, object value, CacheItemPolicy policy, string regionName = null)
        {
            //CacheItemPolicy policy = new CacheItemPolicy();  //这个对象可以设置这个缓存的过期时间,和关联对象等等等。
            //policy.AbsoluteExpiration = DateTime.Now.AddMinutes(30);  //设置过期时间是当前时间+30分钟,那么30分钟后,这个缓存的项就会被移除
            _cache.Set(key, value, policy, regionName);
        }

        /// <summary>
        /// 使用 CacheItem 实例将某个缓存项插入缓存中,并指定逐出选项(代替过期时间)
        /// </summary>
        /// <param name="item">表示要插入的缓存项的对象</param>
        /// <param name="policy">一个包含该缓存项的逐出详细信息的对象。 此对象提供比简单绝对过期更多的逐出选项。</param>
        public static void Set(CacheItem item, CacheItemPolicy policy) => _cache.Set(item, policy);
        #endregion 存值-复写原值

        #region 存值-只新增,不复写原值
        /// <summary>
        /// 使用键和值将某个缓存项插入缓存中_不复写原值,并指定过期时间
        /// </summary>
        /// <param name="key">要插入的缓存项的唯一标识符</param>
        /// <param name="value">该缓存项的数据</param>
        /// <param name="absoluteExpiration">缓存项的固定的过期日期和时间</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns>如果插入成功,则为 true;如果缓存中已存在具有与 key 相同的键的项,则为 false。</returns>
        public static void Add(string key, object value, DateTimeOffset absoluteExpiration, string regionName = default) => _cache.Add(key, value, absoluteExpiration, regionName);

        /// <summary>
        /// 使用键和值将某个缓存项插入缓存中_不复写原值,并指定逐出选项(代替过期时间)
        /// </summary>
        /// <param name="key">要插入的缓存项的唯一标识符</param>
        /// <param name="value">该缓存项的数据</param>
        /// <param name="policy">一个包含该缓存项的逐出详细信息的对象。 此对象提供比简单绝对过期更多的逐出选项</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns>如果插入成功,则为 true;如果缓存中已存在具有与 key 相同的键的项,则为 false。</returns>
        public static void Add(string key, object value, CacheItemPolicy policy, string regionName = null) => _cache.Add(key, value, policy, regionName);

        /// <summary>
        /// 使用 CacheItem 实例将某个缓存项插入缓存中_不复写原值,并指定逐出选项(代替过期时间)
        /// </summary>
        /// <param name="item">表示要插入的缓存项的对象</param>
        /// <param name="policy">一个包含该缓存项的逐出详细信息的对象。 此对象提供比简单绝对过期更多的逐出选项。</param>
        /// <returns>如果插入成功,则为 true;如果缓存中已存在具有与 key 相同的键的项,则为 false。</returns>
        public static bool Add(CacheItem item, CacheItemPolicy policy) => _cache.Add(item, policy);

        /// <summary>
        /// 使用键和值将某个缓存项插入缓存中_不复写原值,并指定过期时间
        /// </summary>
        /// <param name="key">要插入的缓存项的唯一标识符</param>
        /// <param name="value">该缓存项的数据</param>
        /// <param name="absoluteExpiration">缓存项的固定的过期日期和时间</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns>如果存在具有相同键的缓存项,则为现有的缓存项;否则为 null</returns>
        public static object AddOrGetExisting(string key, object value, DateTimeOffset absoluteExpiration, string regionName = default) => _cache.AddOrGetExisting(key, value, absoluteExpiration, regionName);

        /// <summary>
        /// 使用键和值将某个缓存项插入缓存中_不复写原值,并指定逐出选项(代替过期时间)
        /// </summary>
        /// <param name="key">要插入的缓存项的唯一标识符</param>
        /// <param name="value">该缓存项的数据</param>
        /// <param name="policy">一个包含该缓存项的逐出详细信息的对象。 此对象提供比简单绝对过期更多的逐出选项</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns>如果存在具有相同键的缓存项,则为现有的缓存项;否则为 null</returns>
        public static object AddOrGetExisting(string key, object value, CacheItemPolicy policy, string regionName = default) => _cache.AddOrGetExisting(key, value, policy, regionName);

        /// <summary>
        /// 使用 CacheItem 实例将某个缓存项插入缓存中_不复写原值,并指定逐出选项(代替过期时间)
        /// </summary>
        /// <param name="item">表示要插入的缓存项的对象</param>
        /// <param name="policy">一个包含该缓存项的逐出详细信息的对象。 此对象提供比简单绝对过期更多的逐出选项。</param>
        /// <returns>如果存在具有相同键的缓存项,则为现有的缓存项;否则为 null</returns>
        public static CacheItem AddOrGetExisting(CacheItem item, CacheItemPolicy policy) => _cache.AddOrGetExisting(item, policy);
        #endregion 存值-只新增,不复写原值

        #region 取值
        /// <summary>
        /// 返回某个缓存中的缓存项总数
        /// </summary>
        /// <param name=""></param>
        /// <returns></returns>
        public static long GetCount(string regionName = default) => _cache.GetCount(regionName);

        /// <summary>
        /// 获取某个缓存已使用的内存量(以字节为单位)
        /// </summary>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static long GetLastSize(string regionName = default) => _cache.GetLastSize(regionName);

        /// <summary>
        /// 从缓存中读取某缓存项
        /// </summary>
        /// <param name="key">要获取的缓存项的唯一标识符</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static object Get(string key, string regionName = default) => _cache.Get(key, regionName);

        /// <summary>
        /// 从缓存中读取某缓存项_返回CacheItem
        /// </summary>
        /// <param name="key">要获取的缓存项的唯一标识符</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static CacheItem GetCacheItem(string key, string regionName = default) => _cache.GetCacheItem(key, regionName);

        /// <summary>
        /// 获取与指定的键对应的一组缓存项
        /// </summary>
        /// <param name="keys">要获取的缓存项的唯一标识符</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static IDictionary<string, object> GetValues(IEnumerable<string> keys, string regionName = default) => _cache.GetValues(keys, regionName);

        /// <summary>
        /// 获取与指定的键对应的一组缓存项
        /// </summary>
        /// <param name="regionName">某个缓存集合</param>
        /// <param name="keys">要获取的缓存项的唯一标识符</param>
        /// <returns></returns>
        public static IDictionary<string, object> GetValues(string regionName, params string[] keys) => _cache.GetValues(regionName, keys);
        #endregion 取值

        #region 删除
        /// <summary>
        /// 从缓存中移除某个缓存项
        /// </summary>
        /// <param name="key">要搜索的缓存项的唯一标识符</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static object Remove(string key, string regionName = null) => _cache.Remove(key, regionName);

        /// <summary>
        /// 使用原因从缓存中删除缓存项
        /// </summary>
        /// <param name="key">要移除的缓存项的唯一标识符</param>
        /// <param name="reason">删除项的原因</param>
        /// <param name="regionName">某个缓存集合</param>
        /// <returns></returns>
        public static object Remove(string key, CacheEntryRemovedReason reason, string regionName = null) => Remove(key, reason, regionName);
        #endregion 删除
        #endregion 存、取、删除值,检查是否存在值
    }
}

二、Web应用Net7版(框架内置)

1、MemoryCache示例

2、引用Negut包

using Microsoft.Extensions.Caching.Memory;  // WebAPI框架自带

3、MemoryCache使用教程

(1)添加中间件(Program.cs)

  使用builder.Services.AddMemoryCache();进行添加

 public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();
            builder.Services.AddSwaggerGen();

            builder.Services.AddMemoryCache(options =>  // 1、添加内存缓存中间件(一般用于粘性会话或单机缓存)
            {
                options.SizeLimit = 100;                                    // 缓存的最大大小为100份
                options.ExpirationScanFrequency = TimeSpan.FromSeconds(2);  // 两秒钟查找一次过期项
                options.CompactionPercentage = 0.2;                         // 缓存满了时候压缩20%的优先级较低的数据
                options.TrackStatistics = false;          // 设置是否跟踪内存缓存统计信息。 默认已禁用
                options.TrackLinkedCacheEntries = false;  // 设置是否跟踪链接条目。 默认已禁用
            });

            var app = builder.Build();

            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseSwagger();
                app.UseSwaggerUI();
            }

            app.UseAuthorization();

            app.MapControllers();

            app.Run();
        }
    }

(2)Controller 控制器中使用(MemoryCacheController.cs)

/**
*┌──────────────────────────────────────────────────────────────┐
*│ 描    述:MemoryCache WebAPI使用示例
*│ 作    者:执笔小白
*│ 版    本:1.0
*│ 创建时间:2023-7-20 19:02:56
*└──────────────────────────────────────────────────────────────┘
*┌──────────────────────────────────────────────────────────────┐
*│ 命名空间: MemoryCache_WebAPI.Controllers
*│ 类    名:MemoryCacheController
*└──────────────────────────────────────────────────────────────┘
*/
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;

namespace MemoryCache_WebAPI.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class MemoryCacheController : ControllerBase
    {
        #region 变量
        /// <summary>
        /// 日志
        /// </summary>
        private readonly ILogger<MemoryCacheController> _logger;

        /// <summary>
        /// 内存缓存
        /// </summary>
        private readonly IMemoryCache _memoryCache;

        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        #endregion 变量

        /// <summary>
        /// 
        /// </summary>
        public MemoryCacheController(ILogger<MemoryCacheController> logger, IMemoryCache memoryCache)
        {
            _logger = logger;
            _memoryCache = memoryCache;
        }

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            #region 内存缓存 MemoryCache使用示例

            #region 存值
            string key1 = "myKey1",value1 = "Hello, World!1",
                key2 = "myKey2",value2 = "Hello, World!2",
                key3 = "myKey3",value3 = "Hello, World!3";

            //方式一自定义规则:
            MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions()
                .SetAbsoluteExpiration(TimeSpan.FromMinutes(1))  // 设置一分钟后过期被清除-相对时间
                .SetSlidingExpiration(TimeSpan.FromMinutes(1))   // 设置滑动过期时间;一分钟没有访问则清除
                .SetSize(100)                                    // 设置最大缓存项数量为100份
                .SetPriority(CacheItemPriority.Normal);          // 设置优先级为Normal
            memoryCacheEntryOptions.RegisterPostEvictionCallback((keyInfo, valueInfo, reason, state) =>  // 缓存项过期被清除时的回调方法
            {
                Console.WriteLine($"回调函数输出【键:{keyInfo},值:{valueInfo},被清除;原因:{reason}】");
            });

            _memoryCache.Set(key1, value1, memoryCacheEntryOptions);

            //方式二-相对时间_TimeSpan:
            _memoryCache.Set(key2, value2, TimeSpan.FromMinutes(1));  // 设置一分钟后过期

            //方式三-绝对时间_DateTimeOffset:
            DateTimeOffset dateTimeOffset = new DateTimeOffset().AddMinutes(1);  // 设置一分钟后过期
            _memoryCache.Set(key3, value3, dateTimeOffset);
            #endregion 存值

            #region 取值
            string retrievedValue = _memoryCache.Get<string>(key1) ?? string.Empty;
            #endregion 取值

            #region 检查值是否存在
            bool isExist = _memoryCache.TryGetValue(key2, out string cache);
            #endregion 检查值是否存在

            #region 删除值
            _memoryCache.Remove(key3);
            #endregion 删除值
            #endregion 内存缓存 MemoryCache使用示例

            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}
posted @   ꧁执笔小白꧂  阅读(1495)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示