【问题标题】:C# 4.0 MemoryCache - how to evict dependent cache entries when changes are made to their dependenciesC# 4.0 MemoryCache - 如何在更改依赖项时驱逐依赖项缓存条目
【发布时间】:2011-12-05 23:57:32
【问题描述】:

当对它们所依赖的其他条目进行更改时,我试图从 MemoryCache 中逐出条目。这是通过为依赖键上的依赖项创建缓存条目更改监视器来设置的:

public bool AddToCache(string key, object dataItem, 
    DateTimeOffset absoluteExpiration, IEnumerable<string> dependencyKeys)
{
    bool result = false;

    if (!string.IsNullOrWhiteSpace(key) && dataItem != null)
    {
        CacheItemPolicy policy = new CacheItemPolicy {
            AbsoluteExpiration = absoluteExpiration
        };

        if (masterKeys != null && masterKeys.Any())
        {
            policy.ChangeMonitors.Add(
                this.provider.Cache.
                    CreateCacheEntryChangeMonitor(dependencyKeys));

            foreach (ChangeMonitor monitor in policy.ChangeMonitors)
            {
                monitor.NotifyOnChanged(this.OnDependencyChanged);
            }
        }

        result = this.provider.Cache.Add(key, dataItem, policy);
    }

    return result;
}

OnChangedCallBack 方法是这样的:

private void OnDependencyChanged(object state)
{
    // what do I do here as "state" is always null?
}

项目按预期添加到缓存中,当对受监控的键进行更改时,OnDependencyChanged 方法会按预期调用,但是传递给它的“状态”实例始终为空,这意味着我对依赖项已更改的缓存键一无所知,因此无法执行计划的驱逐。

我在这里错过了什么吗,我是不是走错了路?

【问题讨论】:

  • 嗨,Jibberish,你标记了正确的答案,但我仍然无法理解为什么答案是正确的,我什至找不到 OnChangedCacheEntry 的位置......我面临同样的问题,状态始终为空,你能帮忙解释一下吗?谢谢!

标签: c# .net caching c#-4.0 memorycache


【解决方案1】:

OnChangedCacheEntry 中用作参数的委托是:

public delegate void OnChangedCallback(object state);

所以你必须这样称呼它:

monitor.NotifyOnChanged(delegate {
       OnChangedCacheEntry(OnDependencyChanged(dependencyKeys)); });

然后你就可以访问 OnDependencyChanged 中的依赖键了

private void OnDependencyChanged(object state)
{
    IEnumerable<string> dependencyKeys = (IEnumerable<string>) state;
}

【讨论】:

    【解决方案2】:

    我知道这是一个旧线程,但这是我所拥有的,它似乎有效。

    ...
    
    if (dependencies != null)
    {
        var monitor = MemoryCache.Default.CreateCacheEntryChangeMonitor(dependencies);
        monitor.NotifyOnChanged(delegate { OnChangedCallback(dependencies); });
        policy.ChangeMonitors.Add(monitor);
    }
    
    ...
    
    private static void OnChangedCallback(object state)
    {
        var keys = (IEnumerable<string>) state;
        if (keys != null)
            Logger.InfoFormat("callback - {0}", string.Join("|", keys.ToArray()));
        else
            Logger.InfoFormat("callback - null");
    }
    

    OnChangedCallback(dependencies) 中的 dependencies 参数是原始帖子中缺少的。

    【讨论】:

      【解决方案3】:

      假设您想要做的只是驱逐相关条目,如 OP 所述,您无需担心 NotifyOnChanged。这就是你所需要的:

      public bool AddToCache(string key, object dataItem,
          DateTimeOffset absoluteExpiration, IEnumerable<string> dependencyKeys)
      {
          CacheItemPolicy policy = new CacheItemPolicy();
          policy.AbsoluteExpiration = absoluteExpiration;
      
          ChangeMonitor monitor = MemoryCache.Default.CreateCacheEntryChangeMonitor(dependencyKeys);
          policy.ChangeMonitors.Add(monitor);
      
          return MemoryCache.Default.Add(key, dataItem, policy);
      }
      

      【讨论】:

        猜你喜欢
        • 2018-06-20
        • 1970-01-01
        • 1970-01-01
        • 2021-09-29
        • 2020-09-01
        • 2015-09-30
        • 2014-11-10
        • 2022-12-18
        • 2013-01-30
        相关资源
        最近更新 更多