To do a cache-cleaning function in the Web site (that is, to force the cache to expire before the cache expires), some places in the program use the Httpruntime.cache cache, and the database interaction part uses the caching mechanism provided by ObjectDataSource. Cleaning the Httpruntime.cache cache is simple, as long as
list<string> keys = new list<string> ();
Retrieve application Cache Enumerator
IDictionaryEnumerator enumerator = HttpRuntime.Cache.GetEnumerator ();
Copy all keys, 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]);
It's OK.
This thought that the cache of data sources such as ObjectDataSource is also stored in the Httpruntime.cache, after testing unexpectedly is not, because after the execution of the above code ObjectDataSource still read data from the cache.
Use the reflector decompile to discover that ObjectDataSource is a cache implemented using Httpruntime.cacheinternal. Cacheinternal is internal, so it is not possible to write code calls directly, while Cacheinternal does not provide a way to empty the cache, only through the experiment that _caches._entries is to save the cached Hashtable, So call Cacheinternal with the method of reflection, then get the _caches._entries, and the last clear is OK.
The final code is as follows:
The Cacheinternal property (internal, in memory, Cachemulti type) under HttpRuntime is ObjectDataSource and so on DataSource save cache Manager// Because Cacheinternal, _caches, _entries, etc. are internal or private, they can only be invoked through reflection and may follow.
NET upgrade and fail object Cacheintern = Commonhelper.getpropertyvalue (typeof (HttpRuntime), "cacheinternal") as IEnumerable;
_caches is a IEnumerable field in Cachemulti that holds multiple cachesingle.
IEnumerable _caches = Commonhelper.getfieldvalue (Cacheintern, "_caches") as IEnumerable;
foreach (Object Cachesingle in _caches) {clearcacheinternal (cachesingle); The private static void Clearcacheinternal (object cachesingle) {//_entries is a private Hashtable H for storing cached data in Cachesingle
Ashtable _entries = Commonhelper.getfieldvalue (Cachesingle, "_entries") as Hashtable; _entries.
Clear (); Mary>///Gets the value of the static property propertyname of type types///</summary>///<param name= "type" ></param>/// ;p Aram Name= "PropertyName" ></param>///<returns></returns> 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 ("Cannot find attribute:" + propertyname); ///<summary>///Gets the value of the object's PropertyName property///</summary>///<param name= "obj" ></param>
; <param name= "PropertyName" ></param>///<returns></returns> 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 ("Cannot find attribute:" + 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 ("Cannot find field:" + fieldName);
}
The above method, which is invoked through the crack method, may have potential problems and is therefore for informational purposes only.
Search for another article on Google, the backbone is code, the code of Thought and I, posted over also for reference.
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<object> keys = new List<objeCt> (); 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}); }
}
The above is to asp.net empty cache encountered a detailed analysis of the problem, in order to let everyone better solve such problems, I hope this article for everyone's learning help.