如何在 ASP.Net Core 使用 内存缓存

DotNetCore实战

共 4001字,需浏览 9分钟

 ·

2021-01-26 17:22


ASP.NET Core 是一个轻量级,模块化的框架,常用来在 Windows,Linux 和 MacOS 上构建高性能,现代化的web框架,不像过去的 Asp.NET,在 ASP.NET Core 中并没有内置 Cache 对象,不过你可以通过 nuget 上的扩展实现如下三种 cache:

  • in-memory caching
  • distributed caching
  • response caching

在本文中,我们来看看如何将那些不易变的数据灌到内存中实现 ASP.NET Core application 的高性能,然后我会用一些例子来说明这些概念。

如何启用 in-memory cache

要想将 in-memory cache 集成到 ASP.NET Core 中,就需要将其注入到 ServiceCollection 容器,如下代码所示:


public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddMemoryCache();
}

集成好之后,接下来了解一下缓存的统一接口:IMemoryCache ,代码如下:


public interface IMemoryCache : IDisposable
{
    bool TryGetValue(object key, out object value);
    ICacheEntry CreateEntry(object key);
    void Remove(object key);
}

那如何在 Controller 中使用呢?可以使用 Controller 的构造函数实现注入,如下代码所示:


    public class HomeController : Controller
    {
        private readonly ILogger _logger;
        private IMemoryCache cache;

        public HomeController(ILogger logger, IMemoryCache cache)
        {
           _logger = logger;
        }
    }

到现在为止,in-memory caching 的配置全部做完,现在可以考虑如何实现从 Cache 读取和写入了。

Cache的读取和写入

利用 IMemoryCache 接口的 Set() 可实现向缓存中写入数据,请注意这个 Set() 方法接收两个参数,第一个参数是缓存的名字,第二个参数就是你要缓存的内容,如下代码所示:


        public IActionResult Index()
        {
            cache.Set("IDGKey", DateTime.Now.ToString());
            return View();
        }

从 Cache 中提取内容,需要使用 IMemoryCache 接口的 TryGet() 方法,下面是对 Index 方法的一个修改版本,代码如下:


        public IActionResult Index()
        {
            string key = "IDGKey";

            string obj;
            if (!cache.TryGetValue<string>(key, out obj))
            {
                obj = DateTime.Now.ToString();
                cache.Set<string>(key, obj);
            }

            ViewBag.Cache = obj;

            return View();
        }

还有一个叫做 GetOrCreate 方法,从名字上就能看出来,如果获取不到就会创建一个,如下代码所示:


        public IActionResult Index()
        {
            cache.GetOrCreate<string>("IDGKey", cacheEntry =>
            {
                return DateTime.Now.ToString();
            });

            return View();
        }

对了,除了同步版本的 GetOrCreate,还有一个支持异步的 GetOrCreateAsync

Cache 的过期策略

可以对缓存数据指定过期策略,比如说:绝对过期时间 和 滑动过期时间,前者表示缓存数据的绝对存活时间,时间一到就会立即移除,后者表示指定的时间间隔内数据没有被访问到,那么就会被移除,如果不明白的化,参考 Session 的过期机制。

要想设置过期策略,可以通过 MemoryCacheEntryOptions 类来配置,如下代码所示:


        public IActionResult Index()
        {
            MemoryCacheEntryOptions cacheExpirationOptions = new MemoryCacheEntryOptions();

            cacheExpirationOptions.AbsoluteExpiration = DateTime.Now.AddMinutes(30);

            cacheExpirationOptions.Priority = CacheItemPriority.Normal;

            cache.Set<string>("IDGKey", DateTime.Now.ToString(), cacheExpirationOptions);

            return View();
        }

值得注意的是上面的 Priority 属性,它的应用场景是这样的,当应用程序内存不够时要回收内存的过程中,谁的优先级低就会被优先移除,除了Normal 枚举,还有其他诸如:Low, High, NeverRemove ,除了 NeverRemove ,其他的几种都会被回收机制管控。

新的 Cache 机制还提供了一个🐂👃的方式,那就是 回调函数 注入,意味着当 cache 过期被移除时会自动触发你指定的回调函数,你可以在 回调函数 中做一些你自定义的业务逻辑,比如重新给 cache 注入值,如下代码所示:


        public IActionResult Index()
        {
            MemoryCacheEntryOptions cacheExpirationOptions = new MemoryCacheEntryOptions();

            cacheExpirationOptions.RegisterPostEvictionCallback((obj1, obj2, reason, obj3) =>
            {
                //callback

            }, this);

            cache.Set<string>("IDGKey", DateTime.Now.ToString(), cacheExpirationOptions);

            return View();
        }

你甚至还可以配置两个 cache 的依赖关系,举个例子,如果某一个 cache item 被移除了,你希望它关联的 cache 也要自动移除,看起来是不是很 nice,篇幅有限,我会在后面的文章中和大家阐述如何去实现,如果你很想知道,可先参考微软的MSDN:https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-5.0

译文链接:https://www.infoworld.com/article/3230129/how-to-use-in-memory-caching-in-aspnet-core.html?nsdr=true



往期精彩回顾




【推荐】.NET Core开发实战视频课程 ★★★

.NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划

【.NET Core微服务实战-统一身份认证】开篇及目录索引

Redis基本使用及百亿数据量中的使用技巧分享(附视频地址及观看指南)

.NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

10个小技巧助您写出高性能的ASP.NET Core代码

用abp vNext快速开发Quartz.NET定时任务管理界面

在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

现身说法:实际业务出发分析百亿数据量下的多表查询优化

关于C#异步编程你应该了解的几点建议

C#异步编程看这篇就够了


浏览 44
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报