MemoryCache.AddOrGetExisting的行为描述为:
使用指定的键和值以及绝对过期值将缓存条目添加到缓存中。
它返回:
如果存在具有相同key的缓存条目,则现有缓存条目;否则为空。
具有这些语义的方法的目的是什么?这有什么例子?
MemoryCache.AddOrGetExisting的行为描述为:
使用指定的键和值以及绝对过期值将缓存条目添加到缓存中。
它返回:
如果存在具有相同key的缓存条目,则现有缓存条目;否则为空。
具有这些语义的方法的目的是什么?这有什么例子?
在某些情况下,您只想在不存在匹配条目的情况下创建缓存条目(即,您不想覆盖现有值)。
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的维基百科条目。)
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。如果您使用设置昂贵的资源跟踪机制的自定义更改监视器,这可能会出现问题。通常,当缓存条目被驱逐时,缓存系统会调用Dipose()
您的 ChangeMonitors。这使您有机会取消注册事件等。但是,当AddOrGetExisting
返回现有条目时,您必须自己处理。
我实际上并没有使用过这个,但我想一个可能的用例是,如果您想用特定键的新条目无条件地更新缓存,并且您想显式处理返回的旧条目。