ASP. NET provides three main forms of cache: page-level output cache, user control-level output cache (or segment cache), and cache API.
Early cache; frequent Cache
You should implement caching at each layer of the application. Add cache support to the data layer, business logic layer, UI, or output layer. Memory is currently very cheap-therefore, implementing caching in the entire application in a smart way can greatly improve performance.
Page-level output Cache
The simplest form of cache is to keep the HTML copy sent in response to the request in the memory.
To implement the page output cache, you only need to add an OutputCache command to the page.
<% @ OutputCache Duration = "60" VaryByParam = "*" %>
It supports five attributes (or parameters), two of which are required.
Duration Required attribute. The time when the page should be cached, in seconds. Must be a positive integer.
Location cache Location. Parameters: Any, Client, Downstream, None, Server, or ServerAndClient.
Required attribute of VaryByParam. The name of the variable in the Request. None indicates no change. * Used to create a cache for each variable.
Variables are separated.
VaryByHeader changes cache entries based on changes in the specified header.
VaryByCustom allows you to specify custom changes (for example, "Browser") in global. asax ").
The combination of the required Duration and VaryByParam options can be used to handle most cases. For example, if your product directory allows users to view the directory Page Based on categoryID and page variables, you can set the parameter value to "categoryID; page "VaryByParam caches the product directory for a period of time (if the product is not changed at any time, one hour is acceptable, so the duration is 3600 seconds ). This creates separate cache entries for each directory page of each category. Each entry is counted from its first request for one hour.
Example: VaryByCustom is used to support browser customization.
To make each browser have a separate cache entry, the value of VaryByCustom can be set to "browser ". This function has been built into the cache module and will insert a separate page Cache version for each browser name and major version.
<% @ OutputCache Duration = "60" VaryByParam = "None" VaryByCustom = "browser" %>
Segment cache, user control output Cache
The syntax used by fragment caching is the same as that used by page-level output caching, but it is applied to user controls (. ascx files) instead of Web forms.
The user control also supports the attribute VaryByControl, which changes the control cache based on the value of the server control in the. ascx file. If VaryByControl is specified, You can omit VaryByParam. If all pages use the same user control, you can set the value of Shared to "true ".
<% @ OutputCache Duration = "60" VaryByParam = "*" %>
Cache the user control for 60 seconds, and create a separate cache for each change in the Request.
<% @ OutputCache Duration = "60" VaryByParam = "none" VaryByControl = "myControlName" %>
Cache the user control for 60 seconds, and create a separate cache for each different value of the "myControlName" DownList control.
<% @ OutputCache Duration = "60" VaryByParam = "none" VaryByCustom = "browser" Shared = "true" %>
The user control is cached for 60 seconds, and a cache entry is created for each browser name and major version. Share all pages that reference this user control (as long as all pages reference this control with the same ID ).
Cache API, Using Cache objects
Page-level and user control-level output cache is indeed a way to quickly and easily improve site performance, but in ASP. NET, the real flexibility and powerful functions of the Cache are provided by the Cache object. With Cache objects, you can store any serializable Data Objects and control the expiration method of Cache entries based on the combination of one or more dependencies. These dependencies can include the time since an object was cached, the time since the object was last accessed, changes to files or folders, and changes to other cached objects, after slight processing, you can also include changes to specific tables in the database.
Store data in Cache
The simplest way to store data in a Cache is to assign values to a key, just like a HashTable or Dictionary object:
Cache ["key"] = "value ";
This method stores items in the cache without any dependencies, so it does not expire unless the cache engine deletes the items to provide space for other cached data. To include specific cache dependencies, you can use the Add () or Insert () methods. Each method has several reloads. The only difference between Add () and Insert () Is that Add () returns a reference to a cached object, while Insert () does not return a value (null in C, in VB ).
Example
Cache. Insert ("key", myXMLFileData, new
System. Web. Caching. CacheDependency (Server. MapPath ("users. xml ")));
In this example, the xml data in the file can be inserted into the cache, without reading from the file in future requests. CacheDependency is used to ensure that the cache expires immediately after the file is changed, so that the latest data can be extracted from the file and cached again. If the cached data comes from several files, you can also specify an array of file names.
Cache. Insert ("dependentkey", myDependentData, new
System. Web. Caching. CacheDependency (new string [] {}, new string []
{"Key "}));
In this example, the second data block with the key value "key" can be inserted (depending on whether the first data block exists ). If the key "key" does not exist in the cache, or if the object associated with the key expires or is updated, the "dependentkey" cache entry expires.
Cache. Insert ("key", myTimeSensitiveData, null,
DateTime. Now. AddMinutes (1), TimeSpan. Zero );
Absolute Expiration: In this example, the cache will be cached for one minute, and the cache will expire after one minute. Note: you cannot use either the expiration date or the rolling expiration date (see below.
Cache. Insert ("key", myFrequentlyAccessedData, null,
System. Web. Caching. Cache. NoAbsoluteExpiration,
TimeSpan. FromMinutes (1 ));
Dynamic rolling Expiration: This example caches frequently used data. The data will be kept in the cache until it has not been referenced for up to one minute. Note: Dynamic rolling expiration and absolute expiration cannot be used together.
More options
In addition to the dependencies mentioned above, we can also specify the priority of items (low, high, NotRemovable in sequence, they are in the System. web. caching. cacheItemPriority) and the CacheItemRemovedCallback function called when the cached object expires. Most of the time, the default priority is enough-the cache engine can normally complete tasks and handle cache memory management. The CacheItemRemovedCallback option takes into account some interesting possibilities, but in fact it is rarely used. However, to illustrate this method, I will provide an example of its usage:
CacheItemRemovedCallback example
System. Web. Caching. CacheItemRemovedCallback callback = new System. Web. Caching. CacheItemRemovedCallback (OnRemove );
Cache. Insert ("key", myFile, null,
System. Web. Caching. Cache. NoAbsoluteExpiration,
TimeSpan. Zero,
System. Web. Caching. CacheItemPriority. Default, callback );
...
Public static void OnRemove (string key, object cacheItem,
System. Web. Caching. CacheItemRemovedReason reason)
{
AppendLog ("The cached value with key'" + key +
"'Was removed from the cache. Reason:" +
Reason. ToString ());
}
This example uses any logic defined in the AppendLog () method to record the reason why the cached data expires. When deleting items from the cache and recording the Reason for deletion, you can determine whether the cache is effectively used or whether you may need to increase the memory on the server. Note: callback is a static (Shared in VB) method. We recommend that you use this method because if you do not use it, the instance of the class that saves the callback function will be kept in the memory, to support callback (not required for static/Shared methods ).
This feature has a potential use-Refresh cached data in the background so that you never have to wait for data to be filled, but the data remains relatively new. But in fact, this feature is not applicable to the current version of the cache API, because the callback is not triggered or not completed before the cached items are deleted from the cache. Therefore, the user will frequently send a request to access the cache value, and then find that the cache value is empty and has to wait for the cache value to be refilled. I want to see an additional callback in future ASP. NET versions, which can be called CachedItemExpiredBut.
NotRemovedCallback. If this callback is defined, the execution must be completed before the cache item is deleted.
Cache Data Reference Mode
Whenever we try to access the data in the cache, we should consider a situation where the data may no longer be in the cache. Therefore, the following pattern should be applicable to your access to the cached data. In this case, we assume that the cached data is a data table.
Public DataTable GetCustomers (bool BypassCache)
{
String cacheKey = "CustomersDataTable ";
Object cacheItem = Cache [cacheKey] as DataTable;
If (BypassCache) | (cacheItem = null ))
{
CacheItem = GetCustomersFromDataSource ();
Cache. Insert (cacheKey, cacheItem, null,
DateTime. Now. AddSeconds (GetCacheSecondsFromConfig (cacheKey), TimeSpan. Zero );
}
Return (DataTable) cacheItem;
}
Note the following points about this mode:
1) Some values (such as cacheKey, cacheItem, and cache duration) are defined at one time and only once.
2) You can skip the cache as needed-for example, when a new customer is registered and redirected to the customer list, the best way is to skip the cache and refill the cache with the latest data, this data includes newly inserted customers.
3) the cache can only be accessed once. This method improves performance and ensures that NullReferenceExceptions does not occur because the item exists during the first check, but has expired before the second check.
4) This mode uses the strong type check. The "as" Operator in C # tries to convert the object to the type. If the object fails or is empty, only null (null) is returned ).
5) the duration is stored in the configuration file. Ideally, all cache dependencies (whether file-based, time-based, or other types of Dependencies) should be stored in the configuration file, this allows you to make changes and easily measure performance. We also recommend that you specify the default cache duration. If you do not specify the duration for the used cacheKey, use the default duration for the GetCacheSecondsFromConfig () method.
Sample Code related to this article (CachedDemo. msi, see the example CD in this book) is a helper class that will handle all the above situations and can write only one or two lines of code to access the cached data.
Summary
Caching can greatly improve the performance of applications. Therefore, you should consider designing applications and testing the performance of applications. Applications always benefit from caching more or less. Of course, some applications are more suitable for caching than other applications. A deep understanding of the cache options provided by ASP. NET is an important skill that any ASP. NET developer should master.