using System; using System.Threading; using System.Threading.Tasks; public class CachedValue<T> { private readonly Func<Task<T>> _valueFactory; private readonly TimeSpan _expiration; private T _cachedValue; private DateTime _lastUpdated = DateTime.MinValue; private readonly SemaphoreSlim _semaphore = new(1, 1); public CachedValue(TimeSpan expiration, Func<Task<T>> valueFactory) { _expiration = expiration; _valueFactory = valueFactory; } public async Task<T> GetValueAsync() { var cachedValue = _cachedValue; if (cachedValue != null && DateTime.UtcNow - _lastUpdated <= _expiration) return cachedValue; await _semaphore.WaitAsync(); try { if (_cachedValue == null || DateTime.UtcNow - _lastUpdated > _expiration) { _cachedValue = await _valueFactory(); _lastUpdated = DateTime.UtcNow; } return _cachedValue!; } finally { _semaphore.Release(); } } public void ResetAsync() => _lastUpdated = DateTime.MinValue; }
private readonly CachedValue<int> _summedValue; public MyClass() { _summedValue = new CachedValue<int>(TimeSpan.FromMinutes(10), async () => await GetSummedValue()); } public Task<int> GetSummedValueAsync() => _summedValue.GetValueAsync();
937100cookie-checkC# CachedValue