1y ago · Jan 15, 2025 11:20 AM
Building an in-memory cache using with size limits, sliding expiration, and automatic compaction:
Why this is better than a raw ConcurrentDictionary:
- Automatically evicts items when memory size limit is reached.
- Thread-safe lazy loading with prevents duplicate disk loads when multiple requests ask for the same item simultaneously!
CODE
Microsoft.Extensions.Caching.Memory CSHARP
using Microsoft.Extensions.Caching.Memory;
public class GameAssetCache
{
private readonly IMemoryCache _cache = new MemoryCache(new MemoryCacheOptions
{
SizeLimit = 1024, // Max 1,024 cached items
CompactionPercentage = 0.20 // Evict 20% least-recently-used on full limit
});
public async Task<byte[]> GetOrLoadAssetAsync(string assetName)
{
return await _cache.GetOrCreateAsync(assetName, async entry =>
{
entry.SetSize(1);
entry.SetSlidingExpiration(TimeSpan.FromMinutes(10));
entry.SetAbsoluteExpiration(TimeSpan.FromHours(1));
return await LoadAssetFromDiskAsync(assetName);
})!;
}
}Why this is better than a raw ConcurrentDictionary:
- Automatically evicts items when memory size limit is reached.
- Thread-safe lazy loading with
CODE
GetOrCreateAsync
DevDan · .NET Core & Cloud
Writing clean C# code and microservices since .NET Core 2.1....
Writing clean C# code and microservices since .NET Core 2.1....
The following users thanked DevDan for this post: