【问题标题】:Get always returns null获取总是返回 null
【发布时间】:2020-02-05 09:53:07
【问题描述】:

我的问题是添加 ChangeMonitor 会阻止缓存。 Get 总是返回 null 而不是 data。

没有监视器,数据将被返回。

有人对这种行为有想法吗?

try {
    var x = cache.Get(key);

    if (x != null) {
        extendedList = x as List<HistoryInformation>;
        return extendedList;
    }
    data = await _client.NewGetAllLocationHistoryAsync(data);

    list.AddRange(data.List);

    extendedList = extendHistoryList(list);

    CacheItemPolicy policy = new CacheItemPolicy()
    {
        SlidingExpiration = new TimeSpan(0, 1, 0, 0)
    };

    // By the next four lines of code the cache.Get function always returns null!!!

    policy.ChangeMonitors.Add(cache.CreateCacheEntryChangeMonitor(new string[] { cacheName }));
    policy.RemovedCallback = args => {
        log.Info($"GetHistory:{args.CacheItem.Key} ---> {args.RemovedReason}.");
    };

    var v = cache.Add(key, extendedList, policy);

    // Returns null if the lines  "policy.ChangeMonitors.Add ...
    // and                        "policy.RemovedCallback" part of the code.
    var y = cache.Get(key);
}

【问题讨论】:

  • 您是否阅读过有关缓存监视器的文档?这似乎是一件相当复杂的事情,所以我不会仅仅依靠它。
  • 引用:“并非所有缓存实现都支持缓存条目更改监视器。要确定您的缓存实现是否支持 CacheEntryChangeMonitor 对象,请参阅特定缓存实现的文档。”你用的是什么缓存?是否支持缓存条目更改监控对象?
  • 感谢您的回复。我正在使用内存缓存 (ObjectCache cache = MemoryCache.Default;)。到目前为止,我了解 Windows 文档。内存缓存支持 CacheEntryChangeMOnitor (docs.microsoft.com/de-de/dotnet/api/…)。
  • 您确定cache.Get 返回的是空值吗?它看起来更像是您遇到了一个您忽略并返回 null 的异常。您能否制作一个最小的完整示例来重现您所看到的行为?
  • 是的,这对我来说是有线的。我用 catch (Exception e) { log.Error($"GetHistory: Exception {e.Message}"); 捕获异常}。但是没有抛出异常。加上catch块和缓存声明,已经是一个完整的小例子了。

标签: c# caching memory


【解决方案1】:

您要求它从缓存中删除该项目。

缓存很复杂。这是您应该根据文档非常小心地实施的事情之一。碰巧的是,您要求的是您不想要的东西。

ChangeMonitors 不是指监控缓存的对象。它表示当缓存需要失效时报告的监视器。例如,如果您有一个文件要缓存在内存中,则使用文件更改监视器,因此当磁盘上的文件发生更改时,它会立即在缓存中失效。对于奖励积分,如果缓存中不存在密钥,CacheEntryChangeMonitor 将立即发出已删除通知。将这两种行为放在一起,然后...

  • 您创建了一个新的缓存策略,并使用一个更改监视器来监视键 cache 上的 cacheName
  • 缓存中没有名称由cacheName 指定的键,因此更改监视器立即将该项注册为已删除
  • 您使用键 key 添加缓存项。这成功了,并将项目添加到缓存中。但是,更改监视器说该项目应该失效,因此它会立即从缓存中删除。
  • Get(key) 返回 null,因为它应该是

总而言之:如果您想监控缓存的更改,请使用RemovedCallbackCacheEntryChangeMonitor。如果您想在其他内容发生更改时使缓存项无效,请使用ChangeMonitors

【讨论】:

  • 感谢您的解释。当我正确理解您时,我的第一个错误是我试图监控缓存本身,但监控器是用于监控存储在缓存中的对象。如果我理解正确,例如,我必须监视我的扩展列表?但是,如果我再次调用该函数,从缓存中获取列表并将项目添加到扩展列表,缓存是否会被删除?老实说,我不太了解 ChangeMonitor 的 windows 示例。
  • 我想,我明白了。 CacheEntryChangeMonitor 适用于缓存项(即 key1)依赖于同一缓存中的另一个缓存项(key2)的情况。所以,如果缓存项(key2)发生一些变化,CacheEntryChangeMonitor,(监控key2的key1)必须移除缓存项(key1),这样缓存项(key1)必须重新创建。
  • 六安,谢谢你的帮助!!!无论我仍然不允许直观地投票给你的答案,我希望其他开发者会这样做。
猜你喜欢
  • 1970-01-01
  • 2021-09-02
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
  • 2016-11-02
  • 2014-05-06
  • 2012-06-05
相关资源
最近更新 更多