C# 中的缓存:如何加速应用程序并节省资源

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么缓存是每位 C# 开发人员的超能力

\n

想象一下:您的应用程序每次都要去数据库查询同一个城市列表或汇率。数据库是一种缓慢且昂贵的资源。如果我们告诉您,可以在 1 毫秒内而不是 100 毫秒内响应用户呢?是的,这不是魔法,而是合理的 C# 数据缓存。

\n

缓存是一种将频繁请求的数据临时存储在快速存储(通常是内存)中的技术。在本文中,我们将探讨如何在 .NET 应用程序中引入缓存,既使用内置机制,也使用外部解决方案。您将学习如何正确选择策略,并避免陷入数据过时的陷阱。

\n\n

C# 中的缓存类型:从 MemoryCache 到 Redis

\n

在 .NET 生态系统中,有几种缓存方法。选择取决于您的应用程序架构:单体应用还是微服务,单服务器还是集群。

\n\n

1. 内置 MemoryCache (System.Runtime.Caching / Microsoft.Extensions.Caching.Memory)

\n

最简单、最快速的方法是使用 IMemoryCache。数据存储在进程的内存中。非常适合单线程应用程序或简单的网站。

\n

在 ASP.NET Core 中注册和使用的示例:

\n
// 在 Program.cs 中\nbuilder.Services.AddMemoryCache();\n\n// 在控制器或服务中\npublic class WeatherService\n{\n    private readonly IMemoryCache _cache;\n\n    public WeatherService(IMemoryCache cache)\n    {\n        _cache = cache;\n    }\n\n    public async Task<string> GetWeatherAsync(string city)\n    {\n        string cacheKey = $"weather_{city}";\n\n        // 尝试从缓存中获取数据\n        if (_cache.TryGetValue(cacheKey, out string cachedData))\n        {\n            return cachedData;\n        }\n\n        // 如果没有数据,则加载(例如,从 API)\n        string weatherData = await FetchWeatherFromApi(city);\n\n        // 保存到缓存,有效期 10 分钟\n        var cacheEntryOptions = new MemoryCacheEntryOptions()\n            .SetAbsoluteExpiration(TimeSpan.FromMinutes(10));\n\n        _cache.Set(cacheKey, weatherData, cacheEntryOptions);\n\n        return weatherData;\n    }\n}
\n

关键方法:TryGetValue、Set、Remove。请注意过期策略:绝对过期时间(数据在 N 分钟后精确过期)和 滑动过期时间(数据在访问期间保持有效,并在最后一次请求后 N 分钟内有效)。

\n\n

2. 分布式缓存:通过 IDistributedCache 使用 Redis

\n

如果您的应用程序有多个实例(Web 场、微服务),MemoryCache 就不适用了——每个服务器都会存储自己的副本。这时 Redis 就派上用场了。它作为一个独立的服务器运行,对所有实例共享。

\n

在 C# 中连接 Redis:

\n
// 安装包:Microsoft.Extensions.Caching.StackExchangeRedis\nbuilder.Services.AddStackExchangeRedisCache(options =>\n{\n    options.Configuration = "localhost:6379";\n    options.InstanceName = "SampleInstance";\n});\n\n// 通过 IDistributedCache 使用\npublic class ProductService\n{\n    private readonly IDistributedCache _cache;\n\n    public ProductService(IDistributedCache cache)\n    {\n        _cache = cache;\n    }\n\n    public async Task<Product> GetProductAsync(int id)\n    {\n        string cacheKey = $"product_{id}";\n        var cachedProduct = await _cache.GetStringAsync(cacheKey);\n\n        if (cachedProduct != null)\n        {\n            return JsonSerializer.Deserialize<Product>(cachedProduct);\n        }\n\n        var product = await FetchProductFromDb(id);\n        var serialized = JsonSerializer.Serialize(product);\n\n        await _cache.SetStringAsync(cacheKey, serialized, new DistributedCacheEntryOptions\n        {\n            AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30)\n        });\n\n                

博客

书籍推荐