MemoryCache.AddOrGetExistingの動作は次のように説明されます。
指定されたキーと値および絶対有効期限値を使用して、キャッシュエントリをキャッシュに追加します。
そしてそれが戻ること:
同じキーを持つキャッシュエントリが存在する場合、既存のキャッシュエントリ。それ以外の場合はnull。
これらのセマンティクスを持つメソッドの目的は何ですか?この例は何ですか?
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
変数レベルでより洗練された同等物を可能にする方法、およびテストアンドセットとコンペアアンドスワップに関するウィキペディアのエントリも参照してください。)
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()));
印刷します
(ヌル) 1 1
注意すべきもう 1 つの点:AddOrGetExisting
既存のキャッシュ エントリが見つかった場合、呼び出しに渡された CachePolicy は破棄されません。高価なリソース追跡メカニズムを設定するカスタム変更モニターを使用する場合、これは問題になる可能性があります。通常、キャッシュ エントリが削除されると、キャッシュ システムはDipose()
ChangeMonitor を呼び出します。これにより、イベントなどの登録を解除する機会が得られます。AddOrGetExisting
ただし、既存のエントリを返す場合は、自分で処理する必要があります。
I haven't actually used this, but I guess one possible use case is if you want to unconditionally update the cache with a new entry for a particular key and you want to explicitly dispose of the old entry being returned.