MemoryCache には一定数のアイテムをキャッシュする機能がありますか?
例: データベースから 2000 個のアイテムをキャッシュすることにのみ関心があります。アイテムをキャッシュに追加し続けている間に、指定した数のアイテムを超えた場合、最も古いものから削除できます。
そうでない場合、別のスレッドを使用して定期的にハウスキーピングを行う必要がありますか?
オブジェクトの数を制限するものは組み込まれていません。代わりに、使用されているメモリの量を確認し、CacheMemoryLimit
. を超えると、CacheMemoryLimit
古いアイテムがドロップされます。を使用して、一定時間後にアイテムが自動的に期限切れになるように設定することもできますCacheItemPolicy
。
実際にメモリキャッシュとして使用している場合、これらのアプローチはどちらもより理にかなっています。つまり、メモリ制限とデータの取得コストとのトレードオフが心配な場合、キャッシュからアイテムを削除するタイミングを決定する優れた方法です。自問してみてください:
本当にこれを MemoryCache として使用しようとしていますか? データベースから 2000 個のアイテムしか読み込まれていないのに、なぜ気にするのでしょうか?
メモリのオーバーヘッドが心配な場合、またはアイテムが古くなってしまうのが心配な場合は、オブジェクトの数を指定する以外にキャッシュを管理する (より良い) 方法があります。特定の数のオブジェクトをデータ構造に保持する独自の理由がある場合は、別のクラスの使用を検討してください。
もう 1 つのオプションは、オブジェクトの制限管理を実行する新しい MemoryCache プロバイダーを作成することです。これにより、add や remove などの一部の MemoryCache メソッドがオーバーライドされ、任意の制限 (2000 オブジェクトなど) に達するとアイテムが自動的にロールオフされます。
そのような実装の 1 つは、次のようになります。
public class ObjectLimitMemoryCache : MemoryCache
{
private const int ObjectLimit = 2000;
private const string IndexKey = "ObjectLimitIndexKey";
public ObjectLimitMemoryCache(string name, NameValueCollection config)
: base (name, config)
{
}
new public static ObjectLimitMemoryCache Default { get { return new ObjectLimitMemoryCache(Guid.NewGuid().ToString(), new NameValueCollection());}}
public override bool Add(string key, Object value, DateTimeOffset absoluteExpiration, string region = null)
{
try
{
var indexedKeys = (List<string>)(base.Get(IndexKey) ?? new List<string>());
if (base.Add(key, value, absoluteExpiration))
{
string existingKey;
if (string.IsNullOrEmpty(existingKey = indexedKeys.FirstOrDefault(x=>x == key)))
{
indexedKeys.Add(key);
}
if (base.GetCount() > ObjectLimit)
{
base.Remove(indexedKeys.First());
indexedKeys.RemoveAt(0);
}
base.Add(IndexKey, indexedKeys, new DateTimeOffset(DateTime.Now.AddHours(2)));
return true;
}
return false;
}
catch
{
//Log something and other fancy stuff
throw;
}
}
}
これはテストされていないコードであり、MemoryCache の実装例を示すことのみを目的としています。幸運を!