更新 IMemoryCache 服务器端
Update IMemoryCache server-side
我想在我们的网上商店中缓存一些数据 1 小时,我正在使用 Asp.Net Core 2.1
IMemoryCache
。是否可以每小时自动更新一次缓存?
正常情况下,当网络用户请求过期的缓存数据后,缓存会被刷新。但是缓存过程需要一些时间,我想确保没有用户获得 'slow' 网站,因为他的请求正在重置一些缓存数据。
我找不到任何 IMemoryCache
方法来执行此操作。我认为计划任务有可能每小时(+1 秒?)触发一些更新功能,但是运气不好,计划任务比用户请求晚一点,用户正在更新缓存而不是我的预定任务。
return _cache.GetOrCreate("FullNav", entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
//calculate fullnav
return fullnav;
});
最好的方法是什么?
你可以使用AbsoluteExpiration
DateTime cacheEntry;
// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now;
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetAbsoluteExpiration(TimeSpan.FromHours(1));
// Save data in cache.
_cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
}
return View("Cache", cacheEntry);
GetOrCreate
版本,由@Panagiotis Kavavos
推荐
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.AbsoluteExpiration = TimeSpan.FromHours(1);
return DateTime.Now;
});
return View("Cache", cacheEntry);
编辑
AbsoluteExpiration
Gets or sets an absolute expiration date for the cache entry.
AbsoluteExpirationRelativeToNow
Gets or sets an absolute expiration time, relative to now.
AbsoluteExpirationRelativeToNow 是特定于时间偏移的,而 AbsoluteExpiration 是特定于日期的。
天真的实现:
// add proper code to populate
var x = "hello";
_cache.Set(x, NullChangeToken.Singleton);
Task.Factory.StartNew(async () =>
{
await Task.Delay(TimeSpan.FromHours(1));
// add proper code to repopulate
var y = "new value";
_cache.Set(y, NullChangeToken.Singleton);
});
NullChangeToken
永远不会改变,因此该值不会自动过期。该值将被后续调用 _cache.Set(...)
替换
实现没有考虑到项目可能因内存压力而被清除。我认为将其实现为实例化为单例的服务 class 可能会更好。服务 class 会做同样的事情,但将 "expensive" 项保留在实例变量中。
Panagiotis Kanavos 在评论中给出的最佳答案:
- 使用 Set() 而不是 GetOrCreate() 来强制重置缓存,即使它已经存在。 Link
- 不要使用过期时间,甚至不需要AbsoluteExpiration。
- 创建一个计划任务,每隔 x 次调用此方法
在代码中:
fullnav = ''; //calculate fullnav
_cache.Set("FullNav",fullnav);
调用缓存的全导航时,明智的做法是使用TryGetValue
并在缓存尚不可用时调用设置方法。
我想在我们的网上商店中缓存一些数据 1 小时,我正在使用 Asp.Net Core 2.1
IMemoryCache
。是否可以每小时自动更新一次缓存?
正常情况下,当网络用户请求过期的缓存数据后,缓存会被刷新。但是缓存过程需要一些时间,我想确保没有用户获得 'slow' 网站,因为他的请求正在重置一些缓存数据。
我找不到任何 IMemoryCache
方法来执行此操作。我认为计划任务有可能每小时(+1 秒?)触发一些更新功能,但是运气不好,计划任务比用户请求晚一点,用户正在更新缓存而不是我的预定任务。
return _cache.GetOrCreate("FullNav", entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
//calculate fullnav
return fullnav;
});
最好的方法是什么?
你可以使用AbsoluteExpiration
DateTime cacheEntry;
// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now;
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetAbsoluteExpiration(TimeSpan.FromHours(1));
// Save data in cache.
_cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
}
return View("Cache", cacheEntry);
GetOrCreate
版本,由@Panagiotis Kavavos
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.AbsoluteExpiration = TimeSpan.FromHours(1);
return DateTime.Now;
});
return View("Cache", cacheEntry);
编辑
AbsoluteExpiration
Gets or sets an absolute expiration date for the cache entry.
AbsoluteExpirationRelativeToNow
Gets or sets an absolute expiration time, relative to now.
AbsoluteExpirationRelativeToNow 是特定于时间偏移的,而 AbsoluteExpiration 是特定于日期的。
天真的实现:
// add proper code to populate
var x = "hello";
_cache.Set(x, NullChangeToken.Singleton);
Task.Factory.StartNew(async () =>
{
await Task.Delay(TimeSpan.FromHours(1));
// add proper code to repopulate
var y = "new value";
_cache.Set(y, NullChangeToken.Singleton);
});
NullChangeToken
永远不会改变,因此该值不会自动过期。该值将被后续调用 _cache.Set(...)
实现没有考虑到项目可能因内存压力而被清除。我认为将其实现为实例化为单例的服务 class 可能会更好。服务 class 会做同样的事情,但将 "expensive" 项保留在实例变量中。
Panagiotis Kanavos 在评论中给出的最佳答案:
- 使用 Set() 而不是 GetOrCreate() 来强制重置缓存,即使它已经存在。 Link
- 不要使用过期时间,甚至不需要AbsoluteExpiration。
- 创建一个计划任务,每隔 x 次调用此方法
在代码中:
fullnav = ''; //calculate fullnav
_cache.Set("FullNav",fullnav);
调用缓存的全导航时,明智的做法是使用TryGetValue
并在缓存尚不可用时调用设置方法。