Caching needs to be used in many cases. The rational use of caching can increase the response speed of the program and reduce the access pressure on specific resources. This article mainly introduces your Cache Usage in Winform. I hope you can learn about the Cache Usage scenarios and usage methods. Cache is a medium-and large-sized system that must be considered. To avoid every request from accessing background resources (such as databases), we generally consider some data that can be reused, which is not updated frequently, the stored data can be temporarily stored in a certain way, and subsequent requests can directly access the stored data as needed. This mechanism is called a cache mechanism.
The Cache function of. NET 4.0 is mainly composed of three parts: System. Runtime. Caching, System. Web. Caching. Cache and Output Cache.
System. Runtime. Caching is a cache framework added in. NET 4.0. It mainly uses the MemoryCache object, which exists in the assembly System. Runtime. Caching. dll.
System. web. caching. cache. cache objects that have existed since NET2.0 are generally used in the Web, and can also be used in Winform, but System must be referenced. web. dll.
Output Cache is used in Asp. NET. In versions earlier than ASP. NET 4.0, System. Web. Caching. Cache is used directly to Cache HTML fragments. In ASP. NET 4.0 was redesigned to provide an OutputCacheProvider for developers to expand, but it still uses System by default. web. caching. cache.
1. Customize Hastable cache processing.In addition to the above three caching mechanisms, we can also customize cache storage and use in static objects through HashTable or Dictionary.
For example, I used the factory class in my own programs to create business objects. Because of the creation of business objects and data access layer objects, it is an operation that is called repeatedly on the interface or the middle layer. Therefore, you need to store frequently called objects. When downloading and calling, you can directly extract them from the memory. The following BLLFactory class is a service class creation operation based on generic objects. It uses static objects based on Hashtable for caching.
Copy the Code as follows: /// <summary> /// factory class constructed for the business class /// </summary> /// <typeparam name = "T"> Business Object Type </typeparam> public class BLLFactory <T> where T: class {private static Hashtable objCache = new Hashtable (); private static object syncRoot = new Object ();
/// <Summary> /// create or obtain the Instance of the corresponding business class from the cache // </summary> public static T Instance {get {string CacheKey = typeof (T). fullName; T bll = (T) objCache [CacheKey]; // read from the cache
If (bll = null) {lock (syncRoot) {if (bll = null) {bll = Reflect <T>. create (typeof (T ). fullName, typeof (T ). assembly. getName (). name); // create reflection and cache objCache. add (typeof (T ). fullName, bll) ;}} return bll ;}}}
2. Use the. NET4.0 MemoryCache object for caching
The usage of MemoryCache is not described on the Internet, but this is. the new cache object introduced by NET4.0 is estimated to replace the cache module of the original enterprise library, so that.. NET caches can be everywhere, instead of being used based on a specific version of Windows.
First, we will create a MemoryCache-based auxiliary class MemoryCacheHelper to facilitate cache processing.
Copy the Code as follows: /// <summary> /// cache helper class based on MemoryCache /// </summary> public static class MemoryCacheHelper {private static readonly Object _ locker = new object ();
Public static T GetCacheItem <T> (String key, Func <T> cachePopulate, TimeSpan? SlidingExpiration = null, DateTime? AbsoluteExpiration = null) {if (String. isNullOrWhiteSpace (key) throw new ArgumentException ("Invalid cache key"); if (cachePopulate = null) throw new ArgumentNullException ("cachePopulate "); if (slidingExpiration = null & absoluteExpiration = null) throw new ArgumentException ("Either a sliding expiration or absolute must be provided ");
If (MemoryCache. default [key] = null) {lock (_ locker) {if (MemoryCache. default [key] = null) {var item = new CacheItem (key, cachePopulate (); var policy = CreatePolicy (slidingExpiration, absoluteExpiration );
MemoryCache. Default. Add (item, policy );}}}
Return (T) MemoryCache. Default [key];}
Private static CacheItemPolicy CreatePolicy (TimeSpan? SlidingExpiration, DateTime? AbsoluteExpiration) {var policy = new CacheItemPolicy ();
If (absoluteExpiration. HasValue) {policy. AbsoluteExpiration = absoluteExpiration. Value;} else if (slidingExpiration. HasValue) {policy. SlidingExpiration = slidingExpiration. Value ;}
Policy. Priority = CacheItemPriority. Default;
Return policy ;}}
This helper class has only one public method, namely GetCacheItem. When using it, you need to specify the key and the processing proxy for obtaining data, as well as the cache expiration time, whether it is based on TimeSpan or based on absolute time, select one.
Under what circumstances will we use the helper classes above?
If a person ID is used in a workflow module and the person ID needs to be escaped, we generally know that the person information is stored in the permission system module, if you need to frequently escape the personnel ID in the workflow, you need to call the interface module of the permission system by using the method, so that the cache module can be used for optimization.
The copy code is as follows: void gridview1_mmcolumndisplaytext (object sender, DevExpress. xtraGrid. views. base. customColumnDisplayTextEventArgs e) {if (e. column. fieldName. equals ("ProcUser") | e. column. fieldName. equals ("ProcUid") | e. column. fieldName. equals ("UserId") {if (e. value! = Null) {e. DisplayText = SecurityHelper. GetUserFullName (e. Value. ToString ());}}}
SecurityHelper. GetUserFullName is a cache-based secondary encapsulation of the call. The specific logic is as follows.
Copy the Code as follows: // <summary> // obtain the full name of a user based on the user ID, and put it in the cache /// </summary> /// <param name = "userId"> User ID </param> /// <returns> </returns> public static string GetUserFullName (string userId) {string key = "Security_UserFullName" + userId; string fullName = MemoryCacheHelper. getCacheItem <string> (key, delegate () {return BLLFactory <User>. instance. getFullNameByID (userId. toInt32 () ;}, new TimeSpan (0, 30, 0); // return fullName ;}
The MemoryCacheHelper method GetCacheItem contains Func <T> I used an anonymous function to obtain the cached value.
The copy code is as follows: delegate () {return BLLFactory <User>. Instance. GetFullNameByID (userId. ToInt32 ());}
The BLLFactory <User>. Instance. GetFullNameByID is called to obtain the corresponding data from the database.
In this way, when the first time or cache expires, the method of the Business Object Class is automatically called to obtain data.
Finally, you can call the GetUserFullName method on the interface to implement cache-based calling. If the program is used for the first time and the specified key has no data, it will be retrieved from the database and will be hit later, the cached data is obtained directly.
The following figure shows the specific implementation effect of the program.
Of course, the above two methods can also simplify code operations through AOP injection. However, due to the introduction of AOP, more knowledge points will be involved, and the familiarity with the program is not enough, therefore, cache data is still processed in a more common way.