使用ASP.NET清除缓存的最有效方法

我正在构建一个基于ASP.NET / Umbraco的网站,它是通过实体框架进行非常自定义的数据驱动的,我们不得不缓存大量的数据查询(例如通过关键字搜索),因为它是一个繁忙的网站。

但是当用户创建一个新的数据条目时,我需要清除所有的缓存查询(搜索等),以便新条目在结果中可用。

所以在我的创建,删除和更新方法,我打电话给以下方法:

public static void ClearCacheItems()
{
    var enumerator = HttpContext.Current.Cache.GetEnumerator();

    while (enumerator.MoveNext())
    {
        HttpContext.Current.Cache.Remove(enumerator.Key.ToString());
    }
}

这真的很糟糕吗? 我看不到我该如何清除缓存的项目?


您使用的方法实际上是清除缓存的正确方法,代码中只有一个小错误。 只要原始集合保持不变 ,枚举数就是有效的 。 因此,虽然代码可能在大多数情况下都有效,但在某些情况下可能会出现小错误。 最好是使用下面的代码,它基本上是相同的,但不直接使用枚举器。

List<string> keys = new List<string>();
IDictionaryEnumerator enumerator = Cache.GetEnumerator();

while (enumerator.MoveNext())
  keys.Add(enumerator.Key.ToString());

for (int i = 0; i < keys.Count; i++)
  Cache.Remove(keys[i]);

清除整个ASP.NET缓存只是一个特定的功能域似乎有点矫枉过正。

您可以创建一个中间对象,并将所有缓存的查询存储在那里。 这个对象可能只是一个字典对象的包装。 所有查询都应该使用此对象,而不是直接使用ASP.NET缓存。

然后在需要时将此对象添加到ASP.NET缓存。 当你需要清除查询时,只需到这个对象并清除底层字典。 这是一个示例实现:

    public sealed class IntermediateCache<T>
    {
        private Dictionary<string, T> _dictionary = new Dictionary<string, T>();

        private IntermediateCache()
        {
        }

        public static IntermediateCache<T> Current
        {
            get
            {
                string key = "IntermediateCache|" + typeof(T).FullName;
                IntermediateCache<T> current = HttpContext.Current.Cache[key] as IntermediateCache<T>;
                if (current == null)
                {
                    current = new IntermediateCache<T>();
                    HttpContext.Current.Cache[key] = current;
                }
                return current;
            }
        }

        public T Get(string key, T defaultValue)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            T value;
            if (_dictionary.TryGetValue(key, out value))
                return value;

            return defaultValue;
        }

        public void Set(string key, T value)
        {
            if (key == null)
                throw new ArgumentNullException("key");

            _dictionary[key] = value;
        }

        public void Clear()
        {
            _dictionary.Clear();
        }
    }

如果我的查询是这样表示的:

    public class MyQueryObject
    {
       ....
    }

然后,我会使用像这样的“区域”缓存:

// put something in this intermediate cache
IntermediateCache<MyQueryObject>.Current.Set("myKey", myObj);

// clear this cache
IntermediateCache<MyQueryObject>.Current.Clear();

Cache类的设计者可以很容易地为它添加一个Clear方法。 但他们没有,它是由设计 - 因此你的代码是坏的

一个问题是如果集合被修改,则通过集合进行枚举的线程影响 。 这会引发错误。

你真的不需要清除整个缓存。 如果服务器需要内存,它将清除它。 缓存访问是按键 (出于某种原因),因此您需要知道您尝试访问的内容。 所以如果你需要删除和项目,通过一个关键。

UPDATE

我的建议是设计缓存,清除缓存很容易。 例如,用一个ID对缓存项目进行分组(创建一个用于保存相关缓存结果的类),并将该ID用作关键字。 每当与该ID相关的内容发生更改时,请清除该ID的缓存。 十分简单。

链接地址: http://www.djcxy.com/p/60567.html

上一篇: Most Efficient Way Of Clearing Cache Using ASP.NET

下一篇: Caching a user control and clearing that cache programmatically