Introdução: Por que o cache é um componente criticamente importante em aplicações C#
\n\nNo desenvolvimento web moderno, o desempenho da aplicação impacta diretamente a experiência do usuário e os indicadores de negócio. Cada segundo de atraso no carregamento de uma página pode custar 7% de conversões. O cache em C# (.NET) não é apenas uma "opção agradável", mas uma ferramenta obrigatória para qualquer desenvolvedor sério.
\n\nNeste artigo, abordaremos três principais abordagens de cache no ecossistema .NET: Redis, Memcached e soluções integradas (MemoryCache). Você aprenderá quando usar cada ferramenta, como configurar o cache corretamente e evitar erros comuns. O material será útil tanto para desenvolvedores C# iniciantes quanto para engenheiros experientes que desejam sistematizar seus conhecimentos.
\n\n1. Cache integrado: MemoryCache e IDistributedCache
\n\nA plataforma .NET oferece aos desenvolvedores vários mecanismos integrados de cache que não exigem a instalação de serviços de terceiros.
\n\n1.1 MemoryCache — cache local para um único servidor
\n\nIMemoryCache é a forma mais simples e rápida de armazenar dados em cache em C#. Os dados são armazenados na memória RAM do processo atual. Ideal para aplicações single-thread ou aplicações que rodam em um único servidor.
using Microsoft.Extensions.Caching.Memory;\n\npublic class ProductService\n{\n private readonly IMemoryCache _cache;\n \n public ProductService(IMemoryCache cache)\n {\n _cache = cache;\n }\n\n public async Task<Product> GetProductAsync(int id)\n {\n string cacheKey = $"product_{id}";\n \n if (!_cache.TryGetValue(cacheKey, out Product product))\n {\n // Operação custosa (ex.: consulta ao banco de dados)\n product = await GetProductFromDatabaseAsync(id);\n \n var cacheOptions = new MemoryCacheEntryOptions()\n .SetAbsoluteExpiration(TimeSpan.FromMinutes(30))\n .SetSlidingExpiration(TimeSpan.FromMinutes(5))\n .SetSize(1);\n \n _cache.Set(cacheKey, product, cacheOptions);\n }\n \n return product;\n }\n}\n\nPrincipais características do MemoryCache:
\n- \n
- Alta velocidade — os dados são lidos diretamente da RAM \n
- Sem serialização — armazena objetos como estão \n
- Limitação — não funciona em um farm de servidores (cada servidor tem seu próprio cache) \n
- Risco — ao reiniciar a aplicação, o cache é completamente limpo \n
1.2 IDistributedCache — abstração para cache distribuído
\n\nA interface IDistributedCache fornece uma API unificada para trabalhar com qualquer cache distribuído. Você pode alternar entre Redis, SQL Server ou NCache sem alterar o código da lógica de negócios.
using Microsoft.Extensions.Caching.Distributed;\nusing System.Text.Json;\n\npublic class WeatherService\n{\n private readonly IDistributedCache _cache;\n \n public WeatherService(IDistributedCache cache)\n {\n _cache = cache;\n }\n\n public async Task<WeatherForecast> GetForecastAsync(string city)\n {\n string cacheKey = $"weather_{city}";\n string cachedData = await _cache.GetStringAsync(cacheKey);\n \n if (cachedData != null)\n {\n return JsonSerializer.Deserialize<WeatherForecast>(cachedData);\n }\n \n var forecast = await FetchFromApiAsync(city);\n var serialized = JsonSerializer.Serialize(forecast);\n \n await _cache.SetStringAsync(cacheKey, serialized, new DistributedCacheEntryOptions\n {\n AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(15)\n });\n \n return forecast;\n }\n}\n\n