I am using LazyCache and want to have cache refreshed e.g. every hour, but ideally I want the first caller after the cache item expired do not wait for cache reloaded. I wrote the following

public async Task>> GetCarriersAsync() {

    var options = new MemoryCacheEntryOptions
    {
        AbsoluteExpirationRelativeToNow = new TimeSpan(1,0,0),// consider to config
    }.RegisterPostEvictionCallback(
         async  (key, value, reason, state) =>
        {
            await GetCarriersAsync();//will save to cache
            _logger.LogInformation("Carriers are reloaded: " );
        });
    Func<Task<List<KeyValuePair<string, string>>>> cacheableAsyncFunc = () => GetCarriersFromApi();
    var cachedCarriers = await _cache.GetOrAddAsync($"Carriers", cacheableAsyncFunc, options);

    return cachedCarriers;
}

However RegisterPostEvictionCallback is not called when cache item is expired, but only when the next request to the item occurred (and the caller need to wait for a lengthy operation).

The thread Expiration almost never happens on it's own in the background #248 explains that this is by design, and suggests workaround to specify CancellationTokenSource.CancelAfter(TimeSpan.FromHours(1)) instead of SetAbsoluteExpiration.

Unfortunately LazyCache.GetOrAddAsync doesn’t have CancellationToken as a parameter. What is the best way to trigger reload of cache on a scheduled time with minimal waiting time for the first user?

0 Answers