什么是MemoryCache.AddOrGetExisting?

时间:2013-02-05 00:30:38

标签: c# .net memorycache

MemoryCache.AddOrGetExisting的行为描述为:

  

使用指定的键和值将缓存条目添加到缓存中   和绝对到期值。

它返回:

  

如果存在具有相同密钥的缓存条目,则存在现有缓存​​条目;否则,null。

使用这些语义的方法的目的是什么?这是一个什么样的例子?

3 个答案:

答案 0 :(得分:22)

如果匹配的条目尚不存在(也就是说,您不想覆盖现有值),通常情况下您只想创建缓存条目。

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-setcompare-and-swap上的维基百科条目。)

答案 1 :(得分:8)

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返回现有条目时,您必须自己处理。

答案 2 :(得分:4)

我实际上并没有使用过这个,但我想一个可能的用例是,如果你想用一个特定键的新条目无条件地更新缓存,你想要显式处理返回的旧条目。