MemoryCache.AddOrGetExisting の動作は次のように記述されます。
指定されたキーと値、および絶対有効期限値を使用して、キャッシュエントリをキャッシュに追加します。
そしてそれが戻ること:
同じキーを持つキャッシュエントリが存在する場合、既存のキャッシュエントリ。それ以外の場合はnull。
これらのセマンティクスを持つメソッドの目的は何ですか?この例は何ですか?
一致するエントリがまだ存在しない場合(つまり、既存の値を上書きしたくない場合)にのみキャッシュエントリを作成したい場合がよくあります。
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
は実際にはnot既存のキャッシュエントリを更新することを指摘する価値があると思います。
したがって、このコード
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
注意すべきもう1つのこと:AddOrGetExisting
が既存のキャッシュエントリを見つけると、not呼び出しに渡されたCachePolicyを破棄します。これは、高価なリソース追跡メカニズムを設定するカスタム変更モニターを使用する場合に問題になる可能性があります。通常、キャッシュエントリが削除されると、キャッシュシステムはChangeMonitorでDipose()
を呼び出します。これにより、イベントなどの登録を解除することができます。ただし、AddOrGetExisting
が既存のエントリを返す場合は、自分で処理する必要があります。
私は実際にこれを使用していませんが、考えられるユースケースの1つは、特定のキーの新しいエントリでキャッシュを無条件に更新し、返された古いエントリを明示的に破棄する場合です。