我已经创建了自己的高速缓存管理器为一个网站,我发展,我希望找到以清除在某些情况下缓存的最佳方式。

我发现有很多的文章说,正确的方法来清除缓存调用HttpRuntime.Close()

然而,在我的单元测试设置我所说的包封功能HttpRuntime.Close()和高速缓存不被清除出来。

我预期它执行类似于

的东西
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache)
{
    HttpRuntime.Cache.Remove(cacheItem.Key.ToString());
}

在foreach循环在我的包裹功能的伟大工程,但关闭()从来没有工作的权利。

我误解(的HttpRuntime.Close目的)或者是有一些更险恶怎么回事?

有帮助吗?

解决方案

不要使用关闭,但它确实超过了文件说。而文档也说没有用它在处理正常的请求......

这是关闭()的反射源:

[SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
public static void Close() {
    if (_theRuntime.InitiateShutdownOnce()) {
        SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called");
        if (HostingEnvironment.IsHosted) {
            HostingEnvironment.InitiateShutdown();
        } else {
            _theRuntime.Dispose();
        }
    }
}

此外,你不能遍历集合,并在同一时间删除其中的项目,因为这使枚举无效。

那么,试试这个来代替,这不会改变它遍历:

List<string> toRemove = new List<string>();
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) {
    toRemove.Add(cacheItem.Key.ToString());
}
foreach (string key in toRemove) {
    HttpRuntime.Cache.Remove(key);
}

话虽这么说,真的,你应该尝试使用缓存依赖于为您自动清除无效的缓存条目,然后这一切都变得没有必要。

其他提示

  
    

我理解这个问题用枚举,但由于某些原因,缓存似乎并不有问题移除项目,同时通过列表走。

  

如果你深入到细节的实现,你会发现枚举由CacheSingle.CreateEnumerator创建一个新的Hashtable实例枚举创建。

这就是为什么你可以在foreach循环做删除。

您可以简单地实现自己的Cache类,检查以下之一:

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

    private YourCache()
    {
    }

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

    public T Get(string key, T defaultValue)
    {
        if (string.IsNullOrWhiteSpace(key))
            throw new ArgumentNullException("key should not be NULL");

        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();
    }
}

您可以调用从缓存中的项目,甚至可使用以下清除它们:

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

// clear this cache
YourCache<ClassObject>.Current.Clear();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top