【问题标题】:Memory Cache not working in .Net Framework 4内存缓存在 .Net Framework 4 中不起作用
【发布时间】:2019-03-25 06:48:59
【问题描述】:

我的项目是基于 .Net Framework 4.0 构建的,我们使用内置 ObjectCache 作为 MemoryCache,它在 System.Runtime.Caching 中实现。

它之前工作正常,但突然停止在缓存中保存任何内容。当我在缓存上调用Set 方法时,它不会保存任何内容,并且Result View 始终为空,表示Enumeration yielded no results。我仔细检查了代码,发现那里没有任何问题。这真的很简单,如下所示:

var policy = new CacheItemPolicy();
cache = new MemoryCache("MyCache");
cache.Set("item", "item value", policy);
var item = cache.Get("item");
cache.Remove("item"); //when removal is required

但是,在同一台机器上针对 .Net Framework 4 的示例应用程序可以正常工作。我想知道是否有其他人经历过类似的行为,我怎样才能找到这个问题的核心?有什么工具可以提供帮助吗?

【问题讨论】:

  • 如果您将MemoryCache 的名称更改为其他名称,它会重新开始工作吗?
  • 您的结果视图指的是什么,您在哪里将其分配给获取的获取值,在此代码中没有。您是否将item 设为空。还有什么CacheItemPolicy
  • @FrankerZ Cache 实例注册在 Container 中并传递。奇怪的是,当我用新名称注册缓存时。解决的问题仍然是“默认”命名缓存。我需要检查它从哪里获取缓存。
  • @MrinalKamboj 我指的是Result View,我们可以在调试时看到。在将项目设置为缓存后立即为空。如果我调用 cache.GetCount() 我得到 0。CacheItemPolicy 被初始化为其默认值。
  • 即使低于三行连续的代码在我的项目中也不起作用。 Cache = new MemoryCache("MyCache"); CachingPolicy = new CacheItemPolicy(); Cache.Set("item", "value", CachingPolicy); 它将“默认”名称分配给缓存并且不设置值。可能是程序集或框架中的内部错误。

标签: c# .net caching memorycache objectcache


【解决方案1】:

我终于找到了错误的原因。我正在处理具有容器控制的缓存实例的容器。当容器正在处理时,它也在处理我的缓存。而且它无法在已处置的缓存对象上设置值。它应该抛出异常,但它没有,因此整个混乱。未来的读者请注意。

var CachingPolicy = new CacheItemPolicy();
var Cache = new MemoryCache("YourCacheName");
container.RegisterInstance(CachingPolicy);
container.RegisterInstance(Cache);

container.Dispose(); //disposes cache as well. But calling methods on cache object won't throw exception.

//at this point, you should create the cache again, like
CachingPolicy = new CacheItemPolicy();
Cache = new MemoryCache("YourCacheName");
container.RegisterInstance(CachingPolicy);
container.RegisterInstance(Cache);

通过 ILSpy 进一步挖掘 MemoryCache 代码清除了这一点,如果对象被释放,它不会设置任何内容。

if (IsDisposed)
{
    if (collection != null)
    {
        foreach (ChangeMonitor item in collection)
        {
            item?.Dispose();
        }
    }
}
else
{
    MemoryCacheKey memoryCacheKey = new MemoryCacheKey(key);
    MemoryCacheStore store = GetStore(memoryCacheKey);
    store.Set(memoryCacheKey, new MemoryCacheEntry(key, value, absExp, slidingExp, priority, collection, removedCallback, this));
}

【讨论】:

  • 这是哪个容器? Docker 还是依赖注入?
  • @MrinalKamboj 它的 Unity DI 容器。
  • 那么你已经发布了一半的信息,任何被处理的东西都不是一个有效的对象,这与缓存无关,为什么你还要在初始化期间处理缓存
  • 我不确定缓存的生命周期是否与容器一样。我会在 Set 缓存方法上抛出 ObjectDisposedException 至少通知调用者该对象已被处置。另外,我正在处理容器以在登录期间在用户令牌上加载服务。希望现在清楚。
猜你喜欢
  • 1970-01-01
  • 2012-02-12
  • 1970-01-01
  • 1970-01-01
  • 2016-07-20
  • 2015-08-24
  • 2016-09-26
  • 2011-10-25
  • 2017-10-08
相关资源
最近更新 更多