The performance of the project has been at the lower-and lower-level and has been exploring. Since the WCF segment was optimized in the past few weeks, the speed has improved significantly. HoweverProgramIt is not an ideal requirement, so we must continue to work hard!
I. Situation
Some time ago, we found that multiple clients frequently obtain the same data when they connect to the server for the first time. That is to say, each client needs to search for the same data in the database, it is time-consuming to retrieve data from the database multiple times at the same time!
After thinking about it, I decided to cache the basically unchanged data on the server. Finally, when the client gets the data, I don't need to look for the database directly!
I checked on the Internet about the design of the cache mechanism, most of which are based on ASP. NET cache.Article!
Although winform can also use ASP. NET cache, I found that it is not suitable for our project when I study it step by step, mainly for the following reasons:
1. You need to configure the connection string to app. config, and the connection string in our project is separately placed in a specified file (this is the biggest reason that hinders my use of ASP. NET cache)
2. Sometimes you need to use commands to start the SQL Server cache dependency notification (or throughCodeAnd the configuration file needs some modifications.
Recommended articles: ① elaborate on ASP. NET cache and its advanced usage
② ASP. NET cache for petshop
③ Cache container Performance Optimization in a concurrent environment (I): unchangeable hash table
④ System cache resolution 6: database cache dependency
Ii. Learning
Although I cannot apply it to our project, I continue to study it and find some inspiration for custom caching!
Why does ASP. NET cache automatically delete cached data when database data is updated? The most important two aspects are:
1. When cache dependency is enabled, a trigger will be added to the table you want to cache, and a table will record the maximum update time of the cached table (added by the trigger ).
2. Poll the database, that is, enabling a timer to monitor the database all the time.
Think 3
In view of the above ideas, I decided to customize the cache. There are three ideas:
1. Enable a timer to monitor the data table to be cached. (A timer is started every time a cache dependency is created)
2. Define a haschange attribute (learning ASP. NET cache) to record whether the database table data has changed
3. Each table in our database has a updt field, which records the latest update time (I can compare the two times before and after to determine whether the data has changed)
IV. Implementation
1. Define a cache base class (basecache) as follows:
1 Public Class Basecache 2 { 3 Private Datetime? _ Tablemaxupdatetime =Datetime. Now; // The maximum update time of data in the first record table 4 Private String _ Getmaxupdatetimesql = String . Empty; 5 Private Timer _ timer = New Timer ( 3000 ); // Enable the clock to continuously monitor database changes 6 Private Bool _ Haschange =False ; 7 8 Protected Basecache ( String Getmaxupdatetimesql) 9 { 10 _ Getmaxupdatetimesql = Getmaxupdatetimesql; 11 _ Tablemaxupdatetime = Getmaxupdatetimebytable (getmaxupdatetimesql); // obtain the latest time for the first time 12 _ Timer. elapsed + = _ Timer_elapsed; 13 _ Timer. Start (); 14 } 15 16 Protected Bool Haschange // indicates whether the data changes 17 { 18 Get { Return _ Haschange ;} 19 Set {_ Haschange = Value ;} 20 } 21 22 Private Void _ Timer_elapsed ( Object Sender, elapsedeventargs e) // round-robin Database 23 { 24 Try 25 { 26 Datetime? Latestmaxupdatetime = Getmaxupdatetimebytable (_ getmaxupdatetimesql); // obtain the latest update time 27 If (Convert. todatetime (_ tablemaxupdatetime). compareto (latestmaxupdatetime )! = 0 ) // Compare whether the time is the same 28 { 29 _ Tablemaxupdatetime = Latestmaxupdatetime; 30 Haschange = True ; 31 } 32 } 33 Catch (Exception) 34 { 35 Loggingmanager. writelog (loglevel. exception, exception. Message + environment. newline + Exception. stacktrace ); 36 } 37 } 38 39 Private Datetime? Getmaxupdatetimebytable ( String Getmaxupdatetimesql) 40 { 41 Return New Dal. cache (). getmaxupdatetime (getmaxupdatetimesql ); 42 } 43 44 Public Virtual Void Loadcache (){} 45 }
2. define the specific cache dependency productclasscachedependency and inherit the basecache
1 Public Class Productclasscachedependency: basecache 2 { 3 Private Static Dictionary < Int , Proclassinfo> _ productclasscache = New Dictionary < Int , Proclassinfo> ( 150 ); // Define static variables as cache containers 4 Private Static Object _ OBJ = New Object (); 5 6 Public Productclasscachedependency ( String Getmaxupdatetimesql) 7 : Base (Getmaxupdatetimesql) 8 { 9 Loadcache (); 10 } 11 12 Public Override Void Loadcache () 13 { 14 Dictionary < Int , Proclassinfo> productcalssinfo = New Proclass (). getallproductclassinfos (); 15 If (Productcalssinfo! = Null ) 16 { 17 _ Productclasscache. Clear (); 18 _ Productclasscache = Productcalssinfo; 19 } 20 } 21 22 Public Dictionary < Int , Proclassinfo>Productclasscache 23 { 24 Get { Return Updatecache ();} 25 } 26 27 Public Dictionary < Int , Proclassinfo> Updatecache () 28 { 29 If (Haschange) // adopt dual judgment and lock to implement synchronization mechanism 30 { 31 Lock (_ OBJ) 32 { 33 If (Haschange) 34 { 35 Loadcache (); 36 Haschange = False ; 37 } 38 } 39 } 40 Return _ Productclasscache; 41 } 42 }
3. Define the cache proxy cacheproxy and call the cache entry point
1 Public Class Cacheproxy 2 { 3 Private Static Cacheproxy _ cacheproxy = Null ; 4 Private Static Object _ OBJ = New Object (); 6 Private Static Productclasscachedependency _ productclasscache = Null ; 8 9 Private Cacheproxy (){} 10 11 Static Cacheproxy (){} 12 13 Public Static Cacheproxy Cache 14 { 15 Get 16 { 17 If (_ Cacheproxy = Null ) 18 { 19 Lock (_ OBJ) 20 { 21 Return _ Cacheproxy ?? (_ Cacheproxy = New Cacheproxy ()); 22 } 23 } 24 Return _ Cacheproxy; 25 } 26 } 27 33 Public Productclasscachedependency productclasscache 34 { 35 Get { Return _ Productclasscache ?? (_ Productclasscache = New Productclasscachedependency ( " Select max (updt) from prodtproclass " ));}
42// This process may be poor. If you do not use ASP. NET cache to directly upload a table name, you need to improve it. 36 } 43 Public Void Loadallcache () // load all the caches when the program starts. 44 { 46 _ Productclasscache =Productclasscache; 47 } 48 }
4. Call Method
1If (cacheproxy. cache. productclasscache. productclasscache. containskey (1) & cacheproxy. cache. productclasscache. productclasscache! =Null)
{
Cacheproxy. cache. productclasscache. productclasscache [1]
}
Summary
After two or three weeks of hard work, the process has finally ended. In fact, this process is also painful (mainly because the code is not very designed and the head is too big), but the result is quite good!
If you find that the article is not correct, please point out that I know that the Code still needs to be modified. You can give more suggestions and be sure to accept them modestly!
synchronized to: programmer's personal article directory index