千家信息网

ASP.NET清空缓存时遇到的问题怎么解决

发表于:2025-02-23 作者:千家信息网编辑
千家信息网最后更新 2025年02月23日,这篇文章主要介绍"ASP.NET清空缓存时遇到的问题怎么解决",在日常操作中,相信很多人在ASP.NET清空缓存时遇到的问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对
千家信息网最后更新 2025年02月23日ASP.NET清空缓存时遇到的问题怎么解决

这篇文章主要介绍"ASP.NET清空缓存时遇到的问题怎么解决",在日常操作中,相信很多人在ASP.NET清空缓存时遇到的问题怎么解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"ASP.NET清空缓存时遇到的问题怎么解决"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

在网站中要做一个清理缓存的功能(也就是在缓存为到期之前就强制缓存过期),程序中有的地方使用的HttpRuntime.Cache来做的缓存,而和数据库交互部分则使用ObjectDataSource提供的缓存机制。清理HttpRuntime.Cache的缓存很简单,只要

List keys = new List();              // retrieve application Cache enumerator  IDictionaryEnumerator enumerator = HttpRuntime.Cache.GetEnumerator();              // copy all keys that currently exist in Cache              while (enumerator.MoveNext())              {                  keys.Add(enumerator.Key.ToString());              }              // delete every key from cache              for (int i = 0; i < keys.Count; i++)              {                  HttpRuntime.Cache.Remove(keys[i]);              }

就可以了。

本以为ObjectDataSource等数据源的缓存也是保存在HttpRuntime.Cache中,经过测试没想到竟然不是,因为执行上面的代码以后ObjectDataSource仍然是从缓存读取数据。

使用Reflector反编译发现ObjectDataSource是使用HttpRuntime.CacheInternal来实现的缓存,气氛呀,为什么微软总爱搞"特殊化",对外提供一个Cache用,自己偷偷用CacheInternal做缓存。CacheInternal是internal的,因此没法直接写代码调用,同时CacheInternal中也没提供清空缓存的方法,只能通过实验发现_caches._entries是保存缓存的Hashtable,因此就用反射的方法调用CacheInternal,然后拿到_caches._entries,***clear才算ok。

最终代码如下:

//HttpRuntime下的CacheInternal属性(Internal的,内存中是CacheMulti类型)是ObjectDataSource等DataSource保存缓存的管理器  //因为CacheInternal、_caches、_entries等都是internal或者private的,所以只能通过反射调用,而且可能会随着.Net升级而失效      object cacheIntern = CommonHelper.GetPropertyValue(typeof(HttpRuntime), "CacheInternal") as IEnumerable;      //_caches是CacheMulti中保存多CacheSingle的一个IEnumerable字段。      IEnumerable _caches = CommonHelper.GetFieldValue(cacheIntern, "_caches") as IEnumerable;      foreach (object cacheSingle in _caches)      {          ClearCacheInternal(cacheSingle);      }   private static void ClearCacheInternal(object cacheSingle)  {      //_entries是cacheSingle中保存缓存数据的一个private Hashtable   Hashtable _entries = CommonHelper.GetFieldValue(cacheSingle, "_entries") as Hashtable;      _entries.Clear();  }   mary>  /// 得到type类型的静态属性propertyName的值  ///   ///   ///   ///   public static object GetPropertyValue(Type type, string propertyName)  {      foreach (PropertyInfo rInfo in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))      {          if (rInfo.Name == propertyName)          {              return rInfo.GetValue(null, new object[0]);          }      }      throw new Exception("无法找到属性:" + propertyName);  }   ///   /// 得到object对象的propertyName属性的值  ///   ///   ///   ///   public static object GetPropertyValue(object obj, string propertyName)  {      Type type = obj.GetType();      foreach (PropertyInfo rInfo in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))      {          if (rInfo.Name == propertyName)          {              return rInfo.GetValue(obj, new object[0]);          }      }      throw new Exception("无法找到属性:" + propertyName);  }   public static object GetFieldValue(object obj, string fieldName)  {      Type type = obj.GetType();      foreach (FieldInfo rInfo in type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance))      {          if (rInfo.Name == fieldName)          {              return rInfo.GetValue(obj);          }      }      throw new Exception("无法找到字段:" + fieldName);  }

上面方法由于是通过crack的方法进行调用,可能有潜在的问题,因此仅供参考。

private void clearOutputCache()  {      Type ct = this.Cache.GetType();      FieldInfo cif = ct.GetField( "_cacheInternal", BindingFlags.NonPublic | BindingFlags.Instance );      Type cmt = Cache.GetType().Assembly.GetType( "System.Web.Caching.CacheMultiple" );      Type cachekeyType = Cache.GetType().Assembly.GetType( "System.Web.Caching.CacheKey" );      FieldInfo cachesfield = cmt.GetField( "_caches", BindingFlags.NonPublic | BindingFlags.Instance );       object cacheInternal = cif.GetValue( this.Cache );      object caches = cachesfield.GetValue( cacheInternal );       Type arrayType = typeof( Array );      MethodInfo arrayGetter = arrayType.GetMethod( "GetValue", new Type[] { typeof( int ) } );      object cacheSingle = arrayGetter.Invoke( caches, new object[] { 1 } );       FieldInfo entriesField = cacheSingle.GetType().GetField( "_entries", BindingFlags.Instance | BindingFlags.NonPublic );      Hashtable entries = (Hashtable) entriesField.GetValue( cacheSingle );       List keys = new List();      foreach( object o in entries.Keys )      {          keys.Add( o );      }       MethodInfo remove = cacheInternal.GetType().GetMethod( "Remove", BindingFlags.NonPublic | BindingFlags.Instance, null,          new Type[] { cachekeyType, typeof( CacheItemRemovedReason ) }, null );      foreach( object key in keys )      {          remove.Invoke( cacheInternal, new object[] { key, CacheItemRemovedReason.Removed } );      }  }

到此,关于"ASP.NET清空缓存时遇到的问题怎么解决"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

缓存 问题 属性 方法 数据 学习 代码 字段 更多 类型 网站 反射 帮助 实用 特殊 仅供参考 接下来 没想到 也就是 内存 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 杭州金成软件开发公司 怎么修改服务器地址 网络安全考试简讯范文 服务器维修上门 静安区直销软件开发流程 雄安云财务软件网络技术 白山市网络安全和信息化委员会 hypermill数据库怎么用 开发网络安全接入控制 网络技术的正面与负面影响 昆山运营网络技术费用 浙江华数网络技术有限公司 华三服务器不支持百兆 金山软件开发过的杀毒软件 企业信用信息基础数据库在 携程网站数据库被删除 网络安全社团管理规定 化学品数据库技术路线图 与软件开发相关的大学专业 广州考试软件开发市场价 网络安全法宣传目的 循证医学必须检索的数据库 湖南多功能软件开发怎么样 软件开发公司如何核算成本 天谕 官方服务器 花鸟风月 海康威视官网管理服务器图 优派做软件开发 如下属于网络安全术语的是 mysql数据库一个库的大小 多媒体与网络技术题库
0