2013-05-13 45 views
14

我想使用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。”

回答

9

您可以通过使用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); 
+0

我认为这是一个很好的解决方法,如果它工作。谢谢 – Andres 2013-05-16 20:44:35

-2

DateTime.Now.AddDays(1)不会返回DateTimeOffset,而是返回DateTime(AddDays())。

所以这很可能是一个无效的参数。

因此,请尝试DateTimeOffset.Now.AddDays(1)DateTimeOffset)。

+3

-1:有一个[隐含的运营商(http://msdn.microsoft.com/en-us/library /system.datetimeoffset.op_implicit.aspx)从“DateTime”转换为“DateTimeOffset”。 – 2013-05-13 16:27:15

+0

不知道。感谢更新。 – ThaMe90 2013-05-14 06:40:37

3

与ILSpy快速反射调用MemoryCache.Add

if (policy.AbsoluteExpiration != ObjectCache.InfiniteAbsoluteExpiration && policy.SlidingExpiration != ObjectCache.NoSlidingExpiration) 
    { 
     throw new ArgumentException(R.Invalid_expiration_combination, "policy"); 
    } 

所以,绝对的结合和可调过期,本身不支持时,显示此代码。

你应该把自己变成一个自定义的实现。

2

一点点额外的注释,dieguitofernandez答案(这是顺便说一句,一个很好的解决方案):

的ChangeMonitor不是在确切时刻到达则absoluteExpiration菲林,因为过期不每秒检查一次。可能需要几秒钟才能通知第二个缓存项目。 以1天为AbsoluteExpiration并不重要,但如果你需要两个期限是确切的(就像我一样),你必须先使用键和绝对键。

if (cache.Contains("Absolute" + key) && cache.Contains(key)) 

用这种方法可以立即检查两个到期日,并且您可以确定该项目未过期。

(因为我是新来的,我可以张贴此作为评论,对不起!)