87 lines
2.7 KiB
C#
87 lines
2.7 KiB
C#
using Managing.Application.Abstractions;
|
|
using Managing.Core;
|
|
//using Microsoft.Extensions.Caching.Memory;
|
|
using System.Runtime.Caching;
|
|
|
|
namespace Managing.Infrastructure.Storage
|
|
{
|
|
public class TaskCache : ITaskCache
|
|
{
|
|
private MemoryCache _cache { get; } = MemoryCache.Default;
|
|
|
|
private CacheItemPolicy _defaultPolicy { get; } = new CacheItemPolicy()
|
|
{
|
|
SlidingExpiration = TimeSpan.FromMinutes(15),
|
|
};
|
|
|
|
public async Task<T> AddOrGetExisting<T>(string key, Func<Task<T>> valueFactory)
|
|
{
|
|
var asyncLazyValue = new AsyncLazy<T>(valueFactory);
|
|
var existingValue = (AsyncLazy<T>)_cache.AddOrGetExisting(key, asyncLazyValue, _defaultPolicy);
|
|
|
|
if (existingValue != null)
|
|
{
|
|
asyncLazyValue = existingValue;
|
|
}
|
|
|
|
try
|
|
{
|
|
var result = await asyncLazyValue;
|
|
|
|
// The awaited Task has completed. Check that the task still is the same version
|
|
// that the cache returns (i.e. the awaited task has not been invalidated during the await).
|
|
if (asyncLazyValue != _cache.AddOrGetExisting(key, new AsyncLazy<T>(valueFactory), _defaultPolicy))
|
|
{
|
|
// The awaited value is no more the most recent one.
|
|
// Get the most recent value with a recursive call.
|
|
return await AddOrGetExisting(key, valueFactory);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// Task object for the given key failed with exception. Remove the task from the cache.
|
|
_cache.Remove(key);
|
|
// Re throw the exception to be handled by the caller.
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public void Invalidate(string key)
|
|
{
|
|
_cache.Remove(key);
|
|
}
|
|
|
|
public bool Contains(string key)
|
|
{
|
|
return _cache.Contains(key);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
// A snapshot of keys is taken to avoid enumerating collection during changes.
|
|
var keys = _cache.Select(i => i.Key).ToList();
|
|
keys.ForEach(k => _cache.Remove(k));
|
|
}
|
|
|
|
public T Get<T>(string key)
|
|
{
|
|
var existingValue = (AsyncLazy<T>)_cache.Get(key);
|
|
if (existingValue != null) return existingValue.Value.Result;
|
|
return default(T);
|
|
}
|
|
|
|
public virtual List<T> GetCache<T>()
|
|
{
|
|
List<T> list = new List<T>();
|
|
|
|
foreach (var item in _cache)
|
|
{
|
|
list.Add((T)item.Value);
|
|
}
|
|
|
|
return list;
|
|
}
|
|
}
|
|
} |