如何清除asp.net中的服务器缓存?

Posted

技术标签:

【中文标题】如何清除asp.net中的服务器缓存?【英文标题】:How do I clear the server cache in asp.net? 【发布时间】:2013-05-08 01:59:12 【问题描述】:

我发现有两种缓存。有浏览器缓存和服务器缓存。我已经进行了一些搜索,但我还没有找到使用 asp.net(或不使用)清除服务器缓存的清晰分步指南。

(更新)我刚刚了解到,它的代码隐藏在 VB - Visual Basic (dot net) 中。

【问题讨论】:

我会尝试在 IIS 中重新启动站点,或者可能会回收应用程序池。否则,您可能会公开一个手动从缓存中删除所有内容的页面。 @xarzu 什么情况下要清除缓存? 【参考方案1】:

你可以遍历所有的缓存项并一个一个地删除它们:

foreach (System.Collections.DictionaryEntry entry in HttpContext.Current.Cache)
    HttpContext.Current.Cache.Remove(string(entry.Key));

ASP.NET 4.5 C# 的语法更正

foreach (System.Collections.DictionaryEntry entry in HttpContext.Current.Cache)
    HttpContext.Current.Cache.Remove((string)entry.Key);

【讨论】:

+1 @Kenneth,但我认为您的意思是 foreachentry 而不是 de 是的,不知道我是怎么做到的 :-) 你在我的问题的那部分击败了我,所以我把它从我的答案中剔除。不错的答案。 +1 这种方式不会也有上面答案中提到的线程安全问题吗? 我们的 web api 应用程序有一个 List 对象列表,该列表存储在 HttpContext.Current 缓存中。我们通过 HttpContext.Current.Cache.Insert( TheCacheKey, our List, ... ) 的单个调用将数据放入缓存中(如果缓存当前 == null)。我们想为自己提供一个 web api 方法来清除/重置缓存,如果我们愿意,我们可以手动提交。我们在方法中调用 HttpContext.Current.Cache.Remove( TheCacheKey )。它似乎工作。这样做有什么问题吗?【参考方案2】:

迭代存在一个问题:它不是线程安全的。 如果您正在迭代,并且从另一个线程访问缓存,您可能会遇到错误。 这种可能性很低,但对于高负载应用程序来说是一个问题。 仅供参考,一些缓存实现甚至不提供迭代方法。

此外,如果您要清除缓存项,您不想清除应用程序域的每个部分的所有内容,而只想清除与您相关的内容。

当我遇到这个问题时,我通过向所有缓存条目添加自定义 CacheDependency 来解决它。

CacheDependency 是这样定义的:

public class CustomCacheDependency : CacheDependency

    //this method is called to expire a cache entry:
    public void ForceDependencyChange()
    
        this.NotifyDependencyChanged(this, EventArgs.Empty);
    


//this is how I add objects to cache:
HttpContext.Current.Cache.Add(key, //unique key 
            obj, 
            CreateNewDependency(), //the factory method to allocate a dependency
            System.Web.Caching.Cache.NoAbsoluteExpiration,
            new TimeSpan(0, 0, ExpirationInSeconds),
            System.Web.Caching.CacheItemPriority.Default,
            ReportRemovedCallback);

//A list that holds all the CustomCacheDependency objects:
#region dependency mgmt
private List<CustomCacheDependency> dep_list = new List<CustomCacheDependency>();

private CustomCacheDependency CreateNewDependency()

        CustomCacheDependency dep = new CustomCacheDependency();
        lock (dep_list)
        
            dep_list.Add(dep);
        
        return dep;


//this method is called to flush ONLY my cache entries in a thread safe fashion:
private void FlushCache()

        lock (dep_list)
        
            foreach (CustomCacheDependency dep in dep_list) dep.ForceDependencyChange();
            dep_list.Clear();
        
 
#endregion

【讨论】:

或者只使用 "lock(HttpContext.Current.Cache)" 使其线程安全。【参考方案3】:
public void ClearCacheItems()

   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]);
 

【讨论】:

在您的答案中添加解释性文本肯定会帮助其他有类似问题的用户。请考虑添加... 这是一个很好的解决方案。请注意您拥有的任何驱逐代码,因为它也会在删除每个项目时执行。【参考方案4】:

您需要删除已添加到缓存中的项目:

var itemsInCache= HttpContext.Current.Cache.GetEnumerator();

while (itemsInCache.MoveNext())


    HttpContext.Current.Cache.Remove(enumerator.Key);


【讨论】:

enumerator.Key 的值在哪里设置?【参考方案5】:

我不确定您希望使用哪种方法来完成此任务。但是有几种方法,一种方法是 Giorgio Minardi 发布的来自 question 的方法。

其他选择可能是这样的:

using Microsoft.Web.Administration;

public bool RecycleApplicationPool(string appPoolName)


    try
    
        using (ServerManager iisManager = new ServerManager())
        
             iisManager.ApplicationPools[appPoolName].Recycle();
             return true;
        
    
    catch (Exception ex)
    
        throw new Exception("Unhandled Exception");
    

这将成功回收您的应用程序池。这将清除缓存。你有几个选择。请注意,虽然这会清除缓存,但它也会终止任何存在的会话。

希望这会有所帮助。

【讨论】:

是的,如果你重置服务器,它也会清除缓存。这对于 OP 想要的东西来说有点矫枉过正 @Kenneth 是的,但我不确定他想如何完成清除。或者他会在什么环境中进行操作。我想我会提供一种仍然可行的替代方法,只要他将特定的应用程序参数传递给它。它只会清除那个。 你应该在你的答案中添加一条注释,这样你也会杀死任何会话、应用程序对象中的所有数据以及正在执行的任何请求。 这是一段很好的代码,可以偶然发现其他需求。 我有一个更复杂的示例,用于使用绑定构建应用程序池和网站。【参考方案6】:

System.Web.HttpRuntime.UnloadAppDomain() - 重新启动 Web 应用程序,清除缓存,重置 css/js 包

【讨论】:

【参考方案7】:

在页面加载事件中添加此代码..即清除缓存的 http 标头。

Response.CacheControl = "private"
Response.CacheControl = "no-cache"
Response.ClearHeaders()
Response.AppendHeader("Cache-Control", "no-cache")        
Response.AppendHeader("Cache-Control", "private")            
Response.AppendHeader("Cache-Control", "no-store")          
Response.AppendHeader("Cache-Control", "must-revalidate")          
Response.AppendHeader("Cache-Control", "max-stale=0")           
Response.AppendHeader("Cache-Control", "post-check=0")           
Response.AppendHeader("Cache-Control", "pre-check=0")      
Response.AppendHeader("Pragma", "no-cache")
Response.AppendHeader("Keep-Alive", "timeout=3, max=993")          
Response.AppendHeader("Expires", "Mon, 26 Jul 2006 05:00:00 GMT")

【讨论】:

以上是关于如何清除asp.net中的服务器缓存?的主要内容,如果未能解决你的问题,请参考以下文章

如何清除文本框的缓存?? asp.net

Asp.Net WEb中怎么清空缓存?

ASP.NET 应用程序转到 500.21 ...直到 IIS 重置 + 清除临时 ASP.NET 缓存

.net带有参数的页面怎么进行缓存,缓存后可浏览正确页面

在 ASP.NET 中的 Session.Clear() 和 Session.Abandon() 之后会话变量未清除

用工厂模式解决ASP.NET Core中依赖注入的一个烦恼