4

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

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

如果没有,我们是否必须使用另一个线程来定期做家务?

4

2 回答 2

7

它没有任何内置的东西会限制对象的数量。相反,它会检查正在使用多少内存,并将其与CacheMemoryLimit. 如果CacheMemoryLimit超过,它将丢弃较旧的项目。您还可以通过CacheItemPolicy.

如果您真的将它用作内存缓存,这些方法都更有意义。换句话说,如果您担心内存限制和获取数据的成本之间的权衡,这些是确定何时从缓存中逐出项目的好方法。所以问问自己:

我真的想把它用作 MemoryCache 吗?为什么我什至关心从数据库中只加载 2000 个项目?

如果您担心内存开销,或者如果您担心项目过时,还有其他(更好的)方法来管理缓存,而不是指定多个对象。如果您有一些自定义理由在数据结构中保留特定数量的对象,请考虑使用不同的类。

于 2012-09-07T20:13:22.297 回答
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 的示例实现。祝你好运!

于 2012-09-07T21:10:08.273 回答