结合滑动和绝对呼气

时间:2013-05-13 14:31:39

标签: c# .net caching

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

5 个答案:

答案 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)

您有两种选择:

  1. 继承自MemoryCache或其父ObjectCache并实施您自己的缓存机制。
  2. 实施可能more difficult (see Note to Inheritors)
  3. 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)。