我想使用System.Runtime.Caching.MemoryCache来缓存我的一些对象。我想确保该对象每天刷新一次(绝对到期),但如果在最后一小时内没有使用(滑动到期),我也想让它过期。 我试着这样做:
object item = "someitem";
var cache = MemoryCache.Default;
var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now.AddDays(1);
policy.SlidingExpiration = TimeSpan.FromHours(1);
cache.Add("somekey", item, policy);
但我得到一个“ArgumentException”,“AbsoluteExpiration必须是DateTimeOffset.MaxValue或SlidingExpiration必须是TimeSpan.Zero。”
答案 0 :(得分:10)
您可以使用CacheEntryChangeMonitor实现两个方案缓存过期。 插入一个没有绝对过期信息的缓存项,然后使用此项创建一个空的monitorChange,并将其与第二个缓存项链接,在那里您将实际保存slidingTimeOut信息。
object data = new object();
string key = "UniqueIDOfDataObject";
//Insert empty cache item with absolute timeout
string[] absKey = { "Absolute" + key };
MemoryCache.Default.Add("Absolute" + key, new object(), DateTimeOffset.Now.AddMinutes(10));
//Create a CacheEntryChangeMonitor link to absolute timeout cache item
CacheEntryChangeMonitor monitor = MemoryCache.Default.CreateCacheEntryChangeMonitor(absKey);
//Insert data cache item with sliding timeout using changeMonitors
CacheItemPolicy itemPolicy = new CacheItemPolicy();
itemPolicy.ChangeMonitors.Add(monitor);
itemPolicy.SlidingExpiration = new TimeSpan(0, 60, 0);
MemoryCache.Default.Add(key, data, itemPolicy, null);
答案 1 :(得分:4)
ILSpy的快速反映在调用MemoryCache.Add
if (policy.AbsoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration && policy.SlidingExpiration != ObjectCache.NoSlidingExpiration)
{
throw new ArgumentException(R.Invalid_expiration_combination, "policy");
}
因此,本机不支持绝对和滑动过期的组合。
你应该把自己变成一个自定义的实现。
答案 2 :(得分:2)
您有两种选择:
MemoryCache
或其父ObjectCache
并实施您自己的缓存机制。ChangeMonitor
醇>
答案 3 :(得分:2)
对dieguitofernandez的一些补充说明(这是一个非常好的解决方案):
在达到AbsoluteExpiration的确切时刻,ChangeMonitor并没有激烈,因为每秒都不会检查Expiration。可能需要几秒钟才能通知第二个缓存项目。 有一天作为AbsoluteExpiration并不重要,但是如果你需要两个完全的到期(就像我一样)你必须首先使用两个键和absolut键。
if (cache.Contains("Absolute" + key) && cache.Contains(key))
这样可以立即检查两个到期时间,并确保该项目未过期。
(我可以将此作为评论发布,因为我是新来的,对不起!)
答案 4 :(得分:-2)
DateTime.Now.AddDays(1)
不会返回DateTimeOffset,而是返回DateTime(AddDays())。
所以这很可能是一个无效的论点。
相反,请尝试DateTimeOffset.Now.AddDays(1)
(DateTimeOffset)。