MemoryCache.AddOrGetExisting 有啥用?
Posted
技术标签:
【中文标题】MemoryCache.AddOrGetExisting 有啥用?【英文标题】:What is MemoryCache.AddOrGetExisting for?MemoryCache.AddOrGetExisting 有什么用? 【发布时间】:2013-01-19 19:56:11 【问题描述】:MemoryCache.AddOrGetExisting的行为描述为:
使用指定的键和值将缓存条目添加到缓存中 和绝对到期值。
它会返回:
如果存在具有相同key的缓存条目,则现有缓存条目;否则为空。
具有这些语义的方法的目的是什么?有什么例子吗?
【问题讨论】:
结合懒惰***.com/a/15894928/1575281的使用示例 我很高兴我不是唯一一个......我希望在第一次调用时得到我刚刚传入的值,而不是 null 【参考方案1】:在某些情况下,您只想在不存在匹配条目的情况下创建缓存条目(也就是说,您不想覆盖现有值)。
AddOrGetExisting
允许您以原子方式执行此操作。如果没有AddOrGetExisting
,就不可能以原子的、线程安全的方式执行get-test-set。例如:
Thread 1 Thread 2
-------- --------
// check whether there's an existing entry for "foo"
// the call returns null because there's no match
Get("foo")
// check whether there's an existing entry for "foo"
// the call returns null because there's no match
Get("foo")
// set value for key "foo"
// assumes, rightly, that there's no existing entry
Set("foo", "first thread rulez")
// set value for key "foo"
// assumes, wrongly, that there's no existing entry
// overwrites the value just set by thread 1
Set("foo", "second thread rulez")
(另请参阅Interlocked.CompareExchange
方法,它可以在变量级别实现更复杂的等效项,以及test-and-set 和compare-and-swap 上的***条目。)
【讨论】:
很好的解释。但是为什么我们只使用Add
呢?总是使用AddOrGetExisting
不是更好吗?
严格来说这不是“不可能的”,因为您可以将 Get/Set 调用包装在 lock 语句中。【参考方案2】:
LukeH 的回答是正确的。因为其他答案表明该方法的语义可能会有不同的解释,所以我认为值得指出的是,AddOrGetExisting
实际上不会更新现有的缓存条目。
所以这段代码
Console.WriteLine(MemoryCache.Default.AddOrGetExisting("test", "one", new CacheItemPolicy()) ?? "(null)"); Console.WriteLine(MemoryCache.Default.AddOrGetExisting("test", "two", new CacheItemPolicy())); Console.WriteLine(MemoryCache.Default.AddOrGetExisting("test", "three", new CacheItemPolicy()));将打印
(空值) 一 一另一件需要注意的事情:当AddOrGetExisting
找到一个现有的缓存条目时,它不会处理传递给调用的 CachePolicy。如果您使用设置昂贵的资源跟踪机制的自定义更改监视器,这可能会出现问题。通常,当缓存条目被驱逐时,缓存系统会在 ChangeMonitors 上调用Dipose()
。这使您有机会取消注册事件等。但是,当AddOrGetExisting
返回现有条目时,您必须自己处理。
【讨论】:
还要注意:Add
方法或在后台调用 AddOrGetExisting
。【参考方案3】:
我实际上并没有使用过这个,但我想一个可能的用例是,如果您想用特定键的新条目无条件地更新缓存,并且您想显式处理返回的旧条目。
【讨论】:
+1 表示“当您想明确处理旧条目时” 这是有道理的,但我想知道这是不是真的......似乎没有人解释为什么它在您第一次调用 AddOrGetExisting 时返回 null。 有意义的是它第一次返回 null - 从名称来看,它不存在所以它添加 - 否则返回。然后,您还可以使用它来检查该值是否已经存在。 你已经有了现有的值,你正在传递它!除了方便之外,您为什么需要在返回类型中使用它。是的,这太令人惊讶了,但是有旧值的有效用例。以上是关于MemoryCache.AddOrGetExisting 有啥用?的主要内容,如果未能解决你的问题,请参考以下文章