Skip to content

Instantly share code, notes, and snippets.

@kpol
Created September 16, 2019 04:51
Show Gist options
  • Select an option

  • Save kpol/404f551c875c714a39c53e2c24ef0551 to your computer and use it in GitHub Desktop.

Select an option

Save kpol/404f551c875c714a39c53e2c24ef0551 to your computer and use it in GitHub Desktop.
public interface IMemoryCacheExtended : IMemoryCache
{
TItem GetOrCreate<TItem>(object key, Func<ICacheEntry, TItem> factory);
Task<TItem> GetOrCreateOnceAsync<TItem>(object key, Func<ICacheEntry, Task<TItem>> factory);
}
public class MemoryCacheExtended : IMemoryCache
{
private readonly MemoryCache _memoryCache;
private readonly SemaphoreSlim _locker = new SemaphoreSlim(1, 1);
public MemoryCacheExtended(IOptions<MemoryCacheOptions> optionsAccessor)
{
if (optionsAccessor == null) throw new ArgumentNullException(nameof(optionsAccessor));
_memoryCache = new MemoryCache(optionsAccessor);
}
public ICacheEntry CreateEntry(object key) => _memoryCache.CreateEntry(key);
public TItem GetOrCreate<TItem>(object key, Func<ICacheEntry, TItem> factory)
{
_locker.Wait();
try
{
return _memoryCache.GetOrCreate(key, factory);
}
finally
{
_locker.Release();
}
}
public async Task<TItem> GetOrCreateOnceAsync<TItem>(object key, Func<ICacheEntry, Task<TItem>> factory)
{
await _locker.WaitAsync().ConfigureAwait(false);
try
{
return await _memoryCache.GetOrCreateAsync(key, factory).ConfigureAwait(false);
}
finally
{
_locker.Release();
}
}
public void Dispose()
{
_memoryCache?.Dispose();
_locker?.Dispose();
}
public void Remove(object key) => _memoryCache.Remove(key);
public bool TryGetValue(object key, out object value) => _memoryCache.TryGetValue(key, out value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment