Last active
December 8, 2021 19:48
-
-
Save leandromoh/1fc330a851a466e3f64b2c29b27760b9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Concurrent; | |
using System.Threading.Tasks; | |
using System.Timers; | |
public class CustomCache | |
{ | |
private readonly ConcurrentDictionary<string, Task<(object result, DateTime expirationDate)>> dic = new(); | |
private readonly TimeSpan _threshold; | |
private readonly Timer _timer; | |
public CustomCache(TimeSpan threshold) | |
{ | |
_threshold = threshold; | |
_timer = new(TimeSpan.FromMinutes(15).Milliseconds); | |
_timer.Elapsed += OnTimedEvent; | |
_timer.AutoReset = true; | |
_timer.Enabled = true; | |
} | |
private async void OnTimedEvent(object source, ElapsedEventArgs e) | |
{ | |
foreach (var (key, task) in dic) | |
{ | |
var resp = await task; | |
if (IsExpirationValid(resp.expirationDate) is false) | |
dic.TryRemove(key, out var _); | |
} | |
} | |
private bool IsExpirationValid(DateTime expirationDate) | |
{ | |
return DateTime.UtcNow < expirationDate - _threshold; | |
} | |
public async Task<TResult> GetOrAddAsync<TResult>(string key, Func<string, Task<(TResult result, DateTime expirationDate)>> function) | |
{ | |
var usedCache = true; | |
var resp = await dic.GetOrAdd(key, async k => | |
{ | |
usedCache = false; | |
return await function(k); | |
}); | |
if (usedCache is false || IsExpirationValid(resp.expirationDate)) | |
{ | |
return (TResult)resp.result; | |
} | |
dic.TryRemove(key, out var _); | |
resp = await dic.GetOrAdd(key, async k => await function(k)); | |
return (TResult)resp.result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment