MemoryCache具有一定数量的项目

时间:2012-09-07 20:08:30

标签: c# caching

MemoryCache是​​否具有缓存固定数量项目的功能?

e.g。我们只对数据库中的cache 2000项感兴趣。在不断向缓存添加项目的同时,如果超过指定数量的项目,则可以删除最旧的项目。

如果没有,我们是否必须使用另一个线程定期进行保管?

2 个答案:

答案 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的示例实现。祝你好运!