Problem Analysis of cacheName in the asp.net template engine Razor, razorcachename
This article describes the problem of cacheName in the asp.net template engine Razor. Share it with you for your reference. The details are as follows:
I. Why do I use cacheName?
The use of cacheName mainly takes into account that Razor. Parse () dynamically creates an assembly every time it is parsed. If there is a large volume of workers, many Assembly sets will be generated, and a large number of Assembly calls will cause the program to be very slow.
For example:
If you compile 1000 times, the Compilation speed will be very slow.
Static void Main (string [] args) {string cshtml = File. readAllText (@ "E: \ Baidu cloud synchronization disk \ Study \ Net_ASP.NET \ basic Web principles \ RazorCacheNameTest \ HTMLPage1.cshtml"); for (int I = 0; I <1000; I ++) {string html = Razor. parse (cshtml);} Assembly [] asms = AppDomain. currentDomain. getAssemblies (); foreach (Assembly asm in asms) {Console. writeLine (asm. fullName + "\ r \ n");} Console. readKey ();}
Ii. How to solve this problem
Use Razor. Parse () with the cacheName parameter.
Specify a cacheName as cc. The next time Parse () is parsed, it will not be re-compiled (unless the cshtml content is modified, the cacheName name should also be renamed to allow Parse () to Parse the new file)
For (int I = 0; I <1000; I ++) {// if you call it for 1000 times, you can create many Assembly sets using the following method. The performance is very low. string html = Razor. parse (cshtml); // The resolved cshtml file. The "cache name" I gave is cc. Once the file is compiled successfully, // next time I will let you Parse () cc does not need to be compiled repeatedly, and the speed will be very fast. // unless the cshtml content modifies Razor. parse (cshtml, null, "cc ");}
3. How can I ensure that the file indicated by cacheName has been modified?
There are two methods: full file path + file modification time. You can also use the MD5 value of the cshtml file.
For (int I = 0; I <10; I ++) {string cshtml = File. readAllText (fullPath); string cacheName = fullPath + File. getLastWriteTime (fullPath); // full file path + Last file modification time string html = Razor. parse (cshtml, null, cacheName); Console. writeLine (html); Console. readKey ();}
Each time a cshtml file is modified, the value of cacheName changes, and Parse () determines whether to re-compile based on the value of cacheName. If the cshtml file is modified three times during the test, three Assemblies are generated. If the cshtml file is not modified, only one assemblies are generated.
Note: About cacheName.
After testing, it is found that even if the cacheName is written as a fixed value, the Parse result is also the modified content when the cshtml changes. Why?
After decompilation, we found that the Parse method finally calls the GetTemplate method of TemplateService. The Code is as follows:
private ITemplate GetTemplate<T>(string razorTemplate, object model, string cacheName){ Func<string, CachedTemplateItem, CachedTemplateItem> updateValueFactory = null; CachedTemplateItem item; if (razorTemplate == null) { throw new ArgumentNullException("razorTemplate"); } int hashCode = razorTemplate.GetHashCode(); if (!this._cache.TryGetValue(cacheName, out item) || (item.CachedHashCode != hashCode)) { Type templateType = this.CreateTemplateType(razorTemplate, (model == null) ? typeof(T) : model.GetType()); item = new CachedTemplateItem(hashCode, templateType); if (updateValueFactory == null) { updateValueFactory = (n, i) => item; } this._cache.AddOrUpdate(cacheName, item, updateValueFactory); } return this.CreateTemplate(null, item.TemplateType, model);}
The code indicates whether the cache item "TryGetValue (cacheName, out item)" with the name of cacheName exists in the cache. If it does not exist, it is compiled and created. If it exists, then check the hashCode of the cshtml content in the cache. (The HashCode of the string is the same as the HashCode of the same string. The hashCode of different strings has the same probability) is the same as the HashCode of the razorTemplate passed in this time? If it is different, re-compile and create it without using the cache.
Therefore, this can explain why a fixed cacheName is used. As long as the cshtml content is modified, the new content will still be Parse.
Some people may ask: Since cshtml is modified and the new Parse content will be re-transmitted, what is the significance of cacheName? This is because the same probability of HashCode for different strings is very low, but it is not possible that "A and B are not the same, but hashcode is the same". Therefore, if only HashCode is used, the probability is that the "cshtml file has been modified, but the modified HashCode is the same as before, so Parse still executes the old logic ". Therefore, adding cacheName is "double insurance ".
I hope this article will help you design your asp.net program.