Skip to content

Instantly share code, notes, and snippets.

@pkellner
Created December 7, 2019 05:12
Show Gist options
  • Save pkellner/8c8e9d340471b47ca1d341913541a50b to your computer and use it in GitHub Desktop.
Save pkellner/8c8e9d340471b47ca1d341913541a50b to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;
namespace ClassLib.CacheExtension
{
public class TCache<T>
{
private readonly ConcurrentDictionary<object, SemaphoreSlim> _locks =
new ConcurrentDictionary<object, SemaphoreSlim>();
private readonly IMemoryCache _memoryCache;
public TCache(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
public TCache()
{
}
public async Task<T> Get(string key, Func<Task<T>> func, int? cacheTimeOutSeconds = null)
{
var cacheTimeOutSeconds1 = cacheTimeOutSeconds ?? 60;
if (!_memoryCache.TryGetValue(key, out T cacheEntry)) // Look for cache key.
{
var myLock = _locks.GetOrAdd(key, k => new SemaphoreSlim(1, 1));
await myLock.WaitAsync();
try
{
if (!_memoryCache.TryGetValue(key, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = await func();
_memoryCache.Set(key, cacheEntry, new MemoryCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = new TimeSpan(0, 0, cacheTimeOutSeconds1)
});
}
}
finally
{
myLock.Release();
}
}
return cacheEntry;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment