MemoryCache 是否具有缓存固定数量项目的功能?
例如,我们只对从数据库中缓存 2000 个项目感兴趣。在不断向缓存中添加项目的同时,如果超过指定的项目数量,可以删除最旧的项目。
如果没有,我们是否必须使用另一个线程来定期做家务?
它没有任何内置的东西会限制对象的数量。相反,它会检查正在使用多少内存,并将其与CacheMemoryLimit
. 如果CacheMemoryLimit
超过,它将丢弃较旧的项目。您还可以通过CacheItemPolicy
.
如果您真的将它用作内存缓存,这些方法都更有意义。换句话说,如果您担心内存限制和获取数据的成本之间的权衡,这些是确定何时从缓存中逐出项目的好方法。所以问问自己:
我真的想把它用作 MemoryCache 吗?为什么我什至关心从数据库中只加载 2000 个项目?
如果您担心内存开销,或者如果您担心项目过时,还有其他(更好的)方法来管理缓存,而不是指定多个对象。如果您有一些自定义理由在数据结构中保留特定数量的对象,请考虑使用不同的类。
另一种选择是创建一个新的 MemoryCache 提供程序,它为您执行对象限制管理。这将覆盖一些 MemoryCache 方法,例如添加和删除,并在达到任意限制(例如 2000 个对象)后自动滚降项目。
一种这样的实现可能如下所示:
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 的示例实现。祝你好运!