.Net C# MemoryCache 缓存

这篇博客介绍了.NET中的MemoryCache使用,通过示例展示了如何添加和获取缓存数据,以及如何设置缓存过期时间。文章还讨论了缓存雪崩、击穿和穿透问题,并提出了相应的解决方案,如设置随机过期时间、延长缓存有效期和使用布隆过滤器等策略。
摘要由CSDN通过智能技术生成

缓存是一种开发时常用的性能优化手段,.Net自带内存缓存(MemoryCache)可以很方便的使用,下面列出简单用法。

首先通过NuGet添加 Microsoft.Extensions.Hosting、Microsoft.Extensions.Caching.Memory 这两个包。

添加命令:

Install-Package Microsoft.Extensions.Caching.Memory

Install-Package Microsoft.Extensions.Hosting

向缓存中添加数据:

memoryCache.Set(dog.Name, dog, options);

从缓存获取数据(可以直接使用泛型方法指定返回类型):

memoryCache.Get<Dog>(key);

添加时可以使用 await memoryCache.GetOrCreateAsync()方法完成,该方法可以在缓存中没有数据时另外处理获取数据的方式,并将结果添加进缓存中。

参考代码:

internal class CacheDemo
    {
        //该集合当做数据源
        static IEnumerable<Dog> dogs;
        //全局容器
        static IHost host;
        public static async Task DemoMain()
        {
            //向容器添加缓存服务
            host = Host.CreateDefaultBuilder()
                .ConfigureServices(services => services.AddMemoryCache())
                .Build();

            //向数据源填充数据
            dogs = GetDogs().ToList();
            //缓存配置
            MemoryCacheEntryOptions cacheOptions = new()
            {
                //设置缓存10秒过期
                AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10)
            };



            //循环查询缓存中是否有对应数据
            foreach (Dog dog in GetDogs())
            {
                var dogResult = await GetDogAsync(dog.Name);
                Console.WriteLine($"查询结果1:{dogResult}");
            }

            var dogResult2 = GetCacheData("泰迪");
            Console.WriteLine($"查询结果2:{dogResult2}");
            Console.WriteLine("等待11秒缓存过期后再获取");
            await Task.Delay(11000);
            var dogResult3 = GetCacheData("泰迪");
            Console.WriteLine($"查询结果3:{dogResult3}");
            //向缓存中添加泰迪
            SetCacheData(new Dog("泰迪", 1), cacheOptions);
            var dogResult4 = GetCacheData("泰迪");
            Console.WriteLine($"查询结果4:{dogResult4}");
            var dogResult5 = GetCacheData("吉娃娃");
            Console.WriteLine($"查询结果5:{dogResult5}");

        }
        /// <summary>
        /// 从缓存中获取数据
        /// 如果没有则从数据源获取并添加至缓存
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        private static async Task<Dog> GetDogAsync(string name)
        {
            //从容器中获取缓存服务
            IMemoryCache memoryCache = host.Services.GetRequiredService<IMemoryCache>();

            //查询缓存数据,没有则从数据源查询并添加至缓存
            var dogResult = await memoryCache.GetOrCreateAsync(name, t =>
            {
                t.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
                Console.WriteLine($"缓存中没有{name},查询集合数据!");
                Dog dog1 = dogs.SingleOrDefault(d => d.Name.Equals(name));
                return Task.FromResult(dog1);
            });

            return dogResult;
        }
        /// <summary>
        /// 向缓存中添加数据
        /// </summary>
        /// <param name="dog"></param>
        /// <param name="options"></param>
        private static void SetCacheData(Dog dog, MemoryCacheEntryOptions options)
        {
            //从容器中获取缓存服务
            IMemoryCache memoryCache = host.Services.GetRequiredService<IMemoryCache>();

            memoryCache.Set(dog.Name, dog, options);
        }
        /// <summary>
        /// 缓存中获取数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        private static Dog GetCacheData(string key)
        {
            //从容器中获取缓存服务
            IMemoryCache memoryCache = host.Services.GetRequiredService<IMemoryCache>();

            return memoryCache.Get<Dog>(key);
        }

        /// <summary>
        /// 获取所有可爱的狗
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<Dog> GetDogs()
        {
            yield return new Dog("泰迪", 1);
            yield return new Dog("吉娃娃", 2);
            yield return new Dog("哈士奇", 3);
            yield return new Dog("罗威纳", 4);
        }
    }
    /// <summary>
    /// 狗类
    /// </summary>
    /// <param name="Name"></param>
    /// <param name="Id"></param>
    internal record Dog(string Name, int Id);

输出结果:

缓存雪崩:是指同一时间大量缓存失效, 导致大量请求发向后端服务。

向缓存添加数据时,时间可以设置一定范围的随机时间,这是一种避免出现缓存雪崩的简单方法。

缓存击穿:是指热点缓存失效,导致查询该热点数据的请求大量查询后端服务。

如果业务场景允许,可以每次延长缓存时间或者设置为不过期。也可以使用单独的任务来维护热点数据缓存。

缓存穿透:是指大量不存在的数据请求(比如恶意请求)进行查询,此时缓存和后端服务中都没有这些数据,浪费大量资源。

这个时候使用布隆过滤器是个很好的选择。

C# MemoryCache is a caching mechanism provided by the .NET Framework that allows developers to store data in memory for faster access. It is a key-value store where data is stored as key-value pairs and can be accessed using the key. MemoryCache is designed to be used in applications that require frequent access to data, such as web applications that need to retrieve data from a database repeatedly. By storing frequently accessed data in MemoryCache, you can reduce the number of database calls and improve the performance of your application. MemoryCache provides several features, such as time-based expiration, sliding expiration, and the ability to remove items from the cache manually. It also provides thread-safe operations to prevent race conditions when multiple threads access the cache simultaneously. To use MemoryCache in your C# application, you can create an instance of the MemoryCache class and add items to the cache using the Add method. You can also retrieve items from the cache using the Get method and remove items from the cache using the Remove method. Here's an example of how to use MemoryCache in C#: ``` // Create a new instance of the MemoryCache class MemoryCache cache = MemoryCache.Default; // Add an item to the cache with a key of "myKey" and a value of "myValue" cache.Add("myKey", "myValue", DateTimeOffset.Now.AddMinutes(5)); // Retrieve the value of the item with a key of "myKey" string value = cache.Get("myKey") as string; // Remove the item from the cache with a key of "myKey" cache.Remove("myKey"); ``` Overall, MemoryCache is a powerful tool for improving the performance of your C# applications by reducing the number of database calls and providing faster access to frequently accessed data.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个堆栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值