Introducción: Por qué el caché es un componente crítico en aplicaciones C#
\n\nEn el desarrollo web moderno, el rendimiento de la aplicación afecta directamente la experiencia del usuario y los indicadores comerciales. Cada segundo de retraso en la carga de una página puede costarle un 7% de conversiones. El caché en C# (.NET) no es solo una "opción agradable", sino una herramienta obligatoria para cualquier desarrollador serio.
\n\nEn este artículo, analizaremos tres enfoques principales para el caché en el ecosistema .NET: Redis, Memcached y soluciones integradas (MemoryCache). Aprenderá cuándo usar cada herramienta, cómo configurar correctamente el caché y evitar errores típicos. El material será útil tanto para desarrolladores principiantes de C# como para ingenieros experimentados que deseen sistematizar sus conocimientos.
\n\n1. Caché integrado: MemoryCache e IDistributedCache
\n\nLa plataforma .NET proporciona a los desarrolladores varios mecanismos integrados para el caché que no requieren la instalación de servicios de terceros.
\n\n1.1 MemoryCache: caché local para un solo servidor
\n\nIMemoryCache es la forma más simple y rápida de almacenar datos en caché en C#. Los datos se almacenan en la memoria RAM del proceso actual. Es ideal para aplicaciones de un solo subproceso o aplicaciones que se ejecutan en un solo 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 // Operación costosa (por ejemplo, consulta a la BD)\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\nCaracterísticas clave de MemoryCache:
\n- \n
- Alta velocidad — los datos se leen directamente desde la RAM \n
- Sin serialización — almacena objetos tal cual \n
- Limitación — no funciona en una granja de servidores (cada servidor tiene su propio caché) \n
- Riesgo — al reiniciar la aplicación, el caché se borra por completo \n
1.2 IDistributedCache: abstracción para caché distribuido
\n\nLa interfaz IDistributedCache proporciona una API unificada para trabajar con cualquier caché distribuido. Puede cambiar entre Redis, SQL Server o NCache sin modificar el código de la lógica de negocio.
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