Asp.net HttpRuntime Close不会从公布的缓存中删除项目
我为我正在开发的一个网站创建了自己的缓存管理器,我一直在寻找在某些情况下清除缓存的最佳方法 我发现很多文章都说清除缓存的正确方法是调用HttpRuntime.Close 但是,在我的单元测试设置中,我调用了封装的函数HttpRuntime.Close,缓存没有被清除 我希望它能执行类似的操作Asp.net HttpRuntime Close不会从公布的缓存中删除项目,asp.net,caching,asp.net-2.0,Asp.net,Caching,Asp.net 2.0,我为我正在开发的一个网站创建了自己的缓存管理器,我一直在寻找在某些情况下清除缓存的最佳方法 我发现很多文章都说清除缓存的正确方法是调用HttpRuntime.Close 但是,在我的单元测试设置中,我调用了封装的函数HttpRuntime.Close,缓存没有被清除 我希望它能执行类似的操作 foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) { HttpRuntime.Cache.Remove(cacheItem.Key.T
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache)
{
HttpRuntime.Cache.Remove(cacheItem.Key.ToString());
}
foreach循环在我封装的函数中工作得很好,但是Close永远不会正常工作
我是不是误解了HttpRuntime.Close的用途,还是这里发生了更险恶的事情?不要使用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);
}
也就是说,实际上,您应该尝试使用缓存依赖项来自动清除无效的缓存条目,然后所有这些都变得不必要。不要使用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);
}
也就是说,实际上,您应该尝试使用缓存依赖项来自动清除无效的缓存条目,然后所有这些都变得不必要了
我理解枚举的问题,但由于某种原因,在遍历列表时,缓存似乎没有在删除项时遇到问题
如果深入到详细实现,您会发现枚举数是由CacheSSingle.CreateEnumerator创建的,将为枚举创建一个新的哈希表实例
这就是为什么可以在foreach循环中执行remove
我理解枚举的问题,但由于某种原因,在遍历列表时,缓存似乎没有在删除项时遇到问题
如果深入到详细实现,您会发现枚举数是由CacheSSingle.CreateEnumerator创建的,将为枚举创建一个新的哈希表实例
这就是为什么您可以在foreach循环中执行删除操作。您只需实现自己的缓存类,请选中以下一个:
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();
您可以简单地实现自己的缓存类,请检查以下内容:
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();
实际上,我已经测试了我在问题中输入的代码,它运行良好。我理解枚举的问题,但出于某种原因,在遍历列表时,缓存似乎没有在删除项时遇到问题。但这不是我真正的问题。我想说的是,如果我在缓存中有4个项目,我按照我描述的方式循环,那么缓存最终会有0个项目。然而,当我使用Close时,这4项仍然存在。这是因为文档中陈述了一些不完全真实的东西。Close不是用来清除缓存的。哎哟,好的,谢谢你的提醒。缓存依赖项是什么意思?当条目添加到缓存中时,您可以为它们提供依赖项,如超时、文件、另一个缓存条目等,如果此依赖项触发,将清除缓存项。请看,实际上我已经测试了我在问题中输入的代码,它运行良好。我理解枚举的问题,但出于某种原因,在遍历列表时,缓存似乎没有在删除项时遇到问题。但这不是我真正的问题。我想说的是,如果我在缓存中有4个项目,我按照我描述的方式循环,那么缓存最终会有0个项目。然而,当我使用Close时,这4项仍然存在。这是因为文档中陈述了一些不完全真实的东西。Close不是用来清除缓存的。哎哟,好的,谢谢你的提醒。缓存依赖项是什么意思?当条目添加到缓存中时,您可以为它们提供依赖项,如超时、文件、另一个缓存条目等,如果此依赖项触发,将清除缓存项。另见