描述的MemoryCache.AddOrGetExisting的行为:什么是MemoryCache.AddOrGetExisting for?
添加使用指定的关键字和一个值 和绝对过期值的高速缓存条目到缓存中。
并且它返回:
如果使用相同的密钥缓存条目存在,现有的缓存项;否则为空。
具有这些语义的方法的目的是什么?这是什么例子?
描述的MemoryCache.AddOrGetExisting的行为:什么是MemoryCache.AddOrGetExisting for?
添加使用指定的关键字和一个值 和绝对过期值的高速缓存条目到缓存中。
并且它返回:
如果使用相同的密钥缓存条目存在,现有的缓存项;否则为空。
具有这些语义的方法的目的是什么?这是什么例子?
通常情况下,如果匹配条目尚不存在(即,您不想覆盖现有值),则只需创建缓存条目。
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维基百科条目。)
我还没有真正使用过这个,但我猜想一个可能的用例是如果你想无条件地用一个特定键的新条目更新缓存,并且你想显式地处理返回的旧条目。
+1为“当你想明确处置旧条目” – Seph
这是有道理的,但我不知道是否是真的......似乎没有人解释为什么它第一次返回null你调用AddOrGetExisting。 –
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()));
将打印
(null) one one
另外一点需要注意的:当AddOrGetExisting
找到现有的缓存项,它会不处置的的CachePolicy传递给呼叫。如果您使用自定义更改监视器来设置昂贵的资源跟踪机制,则这可能会有问题。通常,当缓存条目被驱逐时,缓存系统会在您的ChangeMonitors上调用Dipose()
。这使您有机会取消注册事件等。但是,AddOrGetExisting
返回现有条目时,您必须亲自处理。
也要注意:在引擎盖下添加'方法或调用'AddOrGetExisting'。 – springy76
一个使用结合懒惰的例子http://stackoverflow.com/a/15894928/1575281 –
嗯,我很高兴我不是唯一一个......我期待得到我刚刚通过的价值回到第一个电话,非空 –