我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解.Net缓存之MemoryCahe

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解.Net缓存之MemoryCahe

1. MemoryCahe

NetCore中的缓存和System.Runtime.Caching很相似,但是在功能上做了增强,缓存的key支持object类型;提供了泛型支持;可以读缓存和单个缓存项的大小做限定,可以设置缓存的压缩比例。

通过实现微软官方的Microsoft.Extensions.Caching里面的IDistributedCache接口实现缓存集成到ASPNETCore中

1.1 简单入门

netcore中缓存相关的类库都在 Microsoft.Extensions.Caching ,使用MemoryCache首先安装包


<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />

注入


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            //添加缓存配置
            services.AddMemoryCache();
        }

使用


        private readonly IMemoryCache _cache;
        public HomeController(IMemoryCache cache)
        {
            _cache = cache;
        }

        [HttpGet]
        public string Set()
        {
            //写
            _cache.Set("login", "4545478244");
            return "";
        }

        [HttpGet]
        public string Get()
        {
            //读
            var value = _cache.Get("login");
            return "";
        }

1.2 过期时间


            //1.最简单使用方式
            _cache.Set("mykey", "myvalue");
            //2.绝对过期时间,3秒后过期
            _cache.Set("key1", "value1", new DateTimeOffset(DateTime.Now.AddSeconds(3)));
            //3.绝对过期时间,效果同上
            _cache.Set("key2", "value2", TimeSpan.FromSeconds(3));
            //4.滑动过期时间,3秒后,即三秒钟内被访问,则重新刷新缓存时间为3秒后
            _cache.Set("key3", "value3", new MemoryCacheEntryOptions
            {
                SlidingExpiration = TimeSpan.FromSeconds(3),
            });
            Console.WriteLine("-----------暂停2秒");
            Thread.Sleep(2000);//暂停2秒
            Console.WriteLine($"key1的值:{_cache.Get("key1") ?? "key1被清除"}");
            Console.WriteLine($"key2的值:{_cache.Get("key2") ?? "key2被清除"}");
            Console.WriteLine($"key3的值:{_cache.Get("key3") ?? "key3被清除"}");
            Console.WriteLine("-----------暂停2秒");
            Thread.Sleep(2000);//再次暂停2秒
            Console.WriteLine($"key1的值:{_cache.Get("key1") ?? "key1被清除"}");
            Console.WriteLine($"key2的值:{_cache.Get("key2") ?? "key2被清除"}");
            Console.WriteLine($"key3的值:{_cache.Get("key3") ?? "key3被清除"}");

在例子中key1,key2都是使用的绝对过期时间,key3使用的相对过期时间,2秒后第一次访问key1、key2、key3都没过期,其中key3的过期时间刷新了,重新设置为3秒后,所以再次暂停2秒后,key1、key2都过期了,key3仍然存在。

程序运行结果如下:

1.2 常用配置

下边的例子介绍netcore中缓存的常用配置,直接看代码


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddMemoryCache(options =>
            {
                //缓存大小
                options.SizeLimit = 3;//如果设置了该值,那么每个set都必须设置size,并且超过了这个值的大小的会自动销毁 
                //缓存满了时,压缩20%(即删除20份优先级低的缓存项)
                options.CompactionPercentage = 0.2;
                //两秒钟查找一次过期项
                options.ExpirationScanFrequency = TimeSpan.FromSeconds(3);
            });
        }

        [HttpGet]
        public string TestSize()
        {
            //SizeLimit配置3
            _cache.Set("item1", "11111", new MemoryCacheEntryOptions
            {
                //缓存大小占1份
                Size = 2
            });
            _cache.Set("item2", "22222", new MemoryCacheEntryOptions
            {
                Size = 2
            });
            var item1 = _cache.Get("item1");//输出 11111
            var item2 = _cache.Get("item2");//输出 null

            return "";
        }

        [HttpGet]
        public string TestOptions()
        {
            //单个缓存项的配置
            MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions()
            {
                //绝对过期时间1
                //AbsoluteExpiration = new DateTimeOffset(DateTime.Now.AddSeconds(2)),
                //绝对过期时间2
                //AbsoluteExpirationRelativeToNow=TimeSpan.FromSeconds(3),
                //相对过期时间
                SlidingExpiration = TimeSpan.FromSeconds(3),
                //优先级,当缓存压缩时会优先清除优先级低的缓存项
                Priority = CacheItemPriority.Low,//优先级等级:Low,Normal,High,NeverRemove
                //缓存大小占1份
                Size = 1
            };
            //注册缓存项被清除时的回调,可以注册多个回调
            cacheEntityOps.RegisterPostEvictionCallback((key, value, reason, state) =>
            {
                Console.WriteLine($"回调函数输出【键:{key},值:{value},被清除的原因:{reason}】");
            });
            _cache.Set("mykey", "myvalue", cacheEntityOps);
            Console.WriteLine($"mykey的值:{_cache.Get("mykey") ?? "mykey缓存被清除了"}");
            Console.WriteLine("------------------暂停3秒");
            Thread.Sleep(3000);
            Console.WriteLine($"mykey的值:{_cache.Get("mykey") ?? "mykey缓存被清除了"}");

            return "";
        }

注意netcore中设置缓存和缓存项大小是没有单位的

缓存被清空的回调函数可以注册多个(System.Runtime.Caching清除缓存的回调只能是一个)。

程序执行结果

1.3 IChangeToken

上边我们已经简单了解了通过滑动过期时间和绝对过期时间来控制缓存的有效性,但是有时缓存的过期与否和时间没有联系,比如我们缓存一个文件的内容,不管缓存多久只要文件没有发生变化缓存都是有效的。在net framework中我们可以通过CacheDependency来控制,在net core中怎么控制呢?net core中我们可以使用IChangeToken接口轻松实现缓存的过期策略。先看一下IChangeToken接口:


    public interface IChangeToken
    {
        // 是否有变化发生
        bool HasChanged { get; }
        // token是否会调用回调函数,为true时才会有效 
        bool ActiveChangeCallbacks { get; }
        // 注册一个回调函数,当有变化时触发回调
        IDisposable RegisterChangeCallback(Action<object> callback, object state);
    }

看一下IChangeToken实现缓存过期策略的两个例子

1.3.1 监控文件

需要安装组件:Microsoft.Extensions.FileProviders.Physical


    internal class Program
    {
        private static void Main(string[] args)
        {
            string fileName = Path.Combine(Environment.CurrentDirectory, "someCacheData.xml");
            var fileInfo = new FileInfo(fileName);
            MemoryCache myCache = new MemoryCache(new MemoryCacheOptions() { });
            MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions();
            //PollingFileChangeToken是IChangeToken的实现类,通过轮询监控文件变化
            cacheEntityOps.AddExpirationToken(new Microsoft.Extensions.FileProviders.Physical.PollingFileChangeToken(fileInfo));
            //缓存失效时,回调函数
            cacheEntityOps.RegisterPostEvictionCallback((key, value, reason, state) => { Console.WriteLine($"文件【{key}】改动了"); });
            //添加缓存,key为文件名,value为文件内容
            myCache.Set(fileInfo.Name, File.ReadAllText(fileName), cacheEntityOps);
            Console.WriteLine(myCache.Get(fileInfo.Name));
        }
    }

PollingFileChangeToken通过轮询来监控文件有没有发生变化,如果文件中的内容发生改变,缓存就会自动过期。

1.3.2 通过代码控制缓存过期


    class Program
    {
        static void Main(string[] args)
        {
            MemoryCache memoryCache = new MemoryCache(new MemoryCacheOptions());
            MemoryCacheEntryOptions cacheEntityOps = new MemoryCacheEntryOptions();
            //使用CancellationChangeToken控制缓存过期
            CancellationTokenSource tokenSource = new CancellationTokenSource();
            cacheEntityOps.AddExpirationToken(new CancellationChangeToken(tokenSource.Token));
            //设置缓存
            memoryCache.Set("mykey", "myvalue", cacheEntityOps);
            Console.WriteLine(memoryCache.Get("mykey") ?? "缓存被清除了");
            //通过代码清除缓存
            tokenSource.Cancel();
            Console.WriteLine(memoryCache.Get("mykey") ?? "缓存被清除了");
        }
    }

tokenSource.Cancel方法发送取消信号,这个方法会触发缓存过期,基于此我们可以通过Cancel方法灵活的实现自定义的缓存策略。

程序执行结果如下:

1.4 引用Nuget包

直接引用我自己简单封装的一个Nuget包(简单封装自己用,不要嘲笑)


    <PackageReference Include="Common.Cache.MemoryCache" Version="1.1.0" />

注入到容器


        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            //注入
            services.AddMemoryCacheExtension();
        }

使用


        # 在需要使用的地方进行注入
        private readonly IMemoryCachimg  _cache;
        public HomeController(IMemoryCachimg cache)
        {
            _cache = cache;
        }

以上就是详解.Net缓存之MemoryCahe的详细内容,更多关于.Net缓存之MemoryCahe的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解.Net缓存之MemoryCahe

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android图片缓存之Bitmap详解(一)

前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap、BitmapFactory这两个类。 Bitmap: Bitmap是Android系统中的图像处理的最重要类之一。用它可
2022-06-06

Android WebView 缓存详解

Android WebView 缓存详解一. 两种缓存类型:页面缓存:加载一个网页时的html、JS、CSS等页面或者资源数据,这些缓存资源是由于浏览器 的行为而产生,开发者只能通过配置HTTP响应头影响浏览器的行为才能间接地影响到这些缓
2023-05-31

MySQL 查询缓存详解

文章目录 MySQL 查询缓存介绍MySQL 查询缓存管理和配置MySQL 缓存机制缓存规则缓存机制中的内存管理 MySQL 查询缓存的优缺点优点缺点 MySQL 查询缓存对性能的影响总结 缓存是一个有效且实用的系统性能
2023-08-16

MySQL缓存策略详解

MySQL缓存方案 一、MySQL缓存方案目的分析1.1、缓存层的作用1.2、缓存层选择1.3、场景分析 二、提升MySQL访问性能的方式2.1、MySQL主从复制2.2、读写分离2.3、连接池2.4、异步连接 三、redi
2023-08-25

JuiceFS 缓存策略详解

对于一个由对象存储和数据库组合驱动的文件系统,缓存是本地客户端与远端服务之间高效交互的重要纽带。读写的数据可以提前或者异步载入缓存,再由客户端在后台与远端服务交互执行异步上传或预取数据。相比直接与远端服务交互,采用缓存技术可以大大降低存储操作的延时并提高数据吞
JuiceFS 缓存策略详解
2014-10-24

Flutter之可滚动组件子项缓存 KeepAlive详解

这篇文章主要为大家详细介绍了Flutter之可滚动组件子项缓存 KeepAlive,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
2022-11-13

.Net执行SQL存储过程之易用轻量工具详解

这篇文章主要为大家介绍了.Net执行SQL存储过程之易用轻量工具详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-20

Spring+EHcache缓存实例详解

一、ehcahe的介绍EhCache 是一个纯Java的进程内缓存框架,具有高速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻
2023-05-31

PHPlaravel缓存cache机制详解

Laravel中的cache为我们提供了三种缓存机制:Redis,memcache,以及框架的文件缓存。本文主要和大家聊聊cache中的文件缓存,感兴趣的小伙伴可以跟随小编一起学习一下
2022-11-13

MyBatis 延迟加载、一级缓存、二级缓存(详解)

使用ORM框架我们更多的是使用其查询功能,那么查询海量数据则又离不开性能,那么这篇中我们就看下mybatis高级应用之延迟加载、一级缓存、二级缓存。使用时需要注意延迟加载必须使用resultMap,resultType不具有延迟加载功能。一
2023-05-31

PHPcms栏目缓存存储位置详解

PHPcms是一种流行的内容管理系统,用于快速搭建网站并管理网站内容。在PHPcms中,栏目缓存是一种重要的优化技术,可以加快网站的访问速度。本文将详细介绍PHPcms栏目缓存的存储位置,同时提供具体的代码示例帮助读者更好地了解和应用这项技
PHPcms栏目缓存存储位置详解
2024-03-15

Spring中的@Cacheable缓存注解详解

这篇文章主要介绍了Spring中的@Cacheable缓存注解详解,数据库查找的流程是先要从磁盘拿到数据,再刷新到内存,再返回数据。磁盘相比于内存来说,速度是很慢的,为了提升性能,就出现了基于内存的缓存,需要的朋友可以参考下
2023-05-20

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录