MemoryCache是否具有缓存固定数量项目的功能?
e.g。我们只对数据库中的cache 2000项感兴趣。在不断向缓存添加项目的同时,如果超过指定数量的项目,则可以删除最旧的项目。
如果没有,我们是否必须使用另一个线程定期进行保管?
答案 0 :(得分:7)
它没有内置任何限制对象数量的内容。相反,它会检查正在使用的内存量,并将其与CacheMemoryLimit
进行比较。如果超出CacheMemoryLimit
,则会删除旧项目。您还可以通过CacheItemPolicy
将项目设置为在一段时间后自动过期。
如果您真的将它用作内存缓存,这些方法都会更有意义。换句话说,如果您担心内存限制与获取数据的成本之间的权衡,这些是确定何时从缓存中逐出项目的好方法。所以问问自己:
我是否真的尝试将其用作MemoryCache?为什么我只关心数据库中只加载了2000个项目?
如果您担心内存开销,或者您担心项目过期,则还有其他(更好)方法来管理缓存,而不是指定多个对象。如果您有一些自定义的理由在数据结构中保留特定数量的对象,请考虑使用其他类。
答案 1 :(得分:1)
另一种选择是创建一个新的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的示例实现。祝你好运!