Caching

  • November 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Caching as PDF for free.

More details

  • Words: 2,468
  • Pages: 5
.Caching with ASP.NET ASP.NET supports three types of caching for Web-based applications: • Page Level Caching (called Output Caching) • Page Fragment Caching (often called Partial-Page Output Caching) • Programmatic or Data Caching Output Caching Page level, or output caching, caches the HTML output of dynamic requests to ASP.NET Web pages. The way ASP.NET implements this (roughly) is through an Output Cache engine. Each time an incoming ASP.NET page request comes in; this engine checks to see if the page being requested has a cached output entry. If it does, this cached HTML is sent as a response; otherwise, the page is dynamically rendered, its output is stored in the Output Cache engine. Output Caching is particularly useful when you have very static pages. It is easy to implement. By simply using the @OuputCache page directive, ASP.NET Web pages can take advantage of this powerful technique. The syntax looks like this: <%@OutputCache Duration="60" VaryByParam="none" %> The Duration parameter specifies how long, in seconds, the HTML output of the Web page should be held in the cache. When the duration expires, the cache becomes invalid and, with the next visit, the cached content is flushed, the ASP.NET Web page's HTML dynamically generated, and the cache repopulated with this HTML. The VaryByParam parameter is used to indicate whether any GET (QueryString) or POST (via a form submit with method="POST") parameters should be used in varying what gets cached. In other words, multiple versions of a page can be cached if the output used to generate the page is different for different values passed in via either a GET or POST. The VaryByParam is a useful setting that can be used to cache different "views" of a dynamic page whose content is generated by GET or POST values. For example, you may have an ASP.NET Web page that reads in a Part number from the QueryString and displays information about a particular widget whose part number matches the QueryString Part number. Imagine for a moment that Output Caching ignored the QueryString parameters altogether (which you can do by setting VaryByParam="none"). If the first user visited the page with QueryString /ProductInfo.aspx?PartNo=4, she would see information out widget #4. The HTML for this page would be cached. The next user now visits and wished to see information on widget #8, a la /ProductInfo.aspx?PartNo=8. If VaryByParam is set to VaryByParam="none", the Output Caching engine will assume that the requests to the two pages are synonymous, and return the cached HTML for widget #4 to the person wishing to see widget #8! To solve for this problem, you can specify that the Output Caching engine should vary its caches based on the PartNo parameter by either specifying it explicitly, like VaryByParam="PartNo", or by saying to vary on all GET/POST parameters, like: VaryByParam="*". The full spec for the @OutputCache lines is: <%@ OutputCache Duration="#ofseconds" Location="Any ¦ Client ¦ Downstream ¦ Server ¦ None" VaryByControl="controlname" VaryByCustom="browser ¦ customstring" VaryByHeader="headers" VaryByParam="parametername" %> Duration is a count in seconds to cache. Location allows the caching to occur on the server, on the client, on a proxy server in between. The default is Any. If you always want server caching (which seems to me to be the most useful choice), change the line to read: <%@ OutputCache Duration="3600" Location="Server" VaryByParam="none"%> VaryByControl is only used by user controls, not on standard web pages.

VaryByCustom="browser" keeps a different copy of the output for each browser name and major version information. So if you have cloaking by browser version going on (which is easy to implement in .NET), then each separate page will get delivered. VaryByCustom="customstring" Allows you to specify a string that will be passed to your code. To make this useful, you must then override the GetVaryByCustomString method in the Global.asax file. For example, place this line in your ASPX file: <%@ OutputCache Duration="3600" Location="Server" VaryByCustom="Referer" VaryByParam="none"%> Then in your Global.asax file add the following code: public override String GetVaryByCustomString(System.Web.HttpContext hcContext, String strCustom) { switch (strCustom) { case "Referer": Uri uriReferrer = hcContext.Request.UrlReferrer; String strRet; if (uriReferrer != null) strRet = uriReferrer.Host; else strRet = null; return strRet; default: return base.GetVaryByCustomString(hcContext, strCustom); } } VaryByHeader allows you to cache based off of some field in the HTTP header sent by the client. The classic example is based off the Accept-Language header line. VaryByParam allows you to cache different versions based off of querystring or post field parameters. So http://www.domain.com/foo.aspx?bar=baz would be cached separately from http://www.domain.com/foo.aspx?bar=bletch Partial-Page Output Caching More often than not, it is impractical to cache entire pages. For example, you may have some content on your page that is fairly static, such as a listing of current inventory, but you may have other information, such as the user's shopping cart, or the current stock price of the company, that you wish to not be cached at all. Since Output Caching caches the HTML of the entire ASP.NET Web page, clearly Output Caching cannot be used for these scenarios: enter Partial-Page Output Caching. Partial-Page Output Caching, or page fragment caching, allows specific regions of pages to be cached. ASP.NET provides a way to take advantage of this powerful technique, requiring that the part(s) of the page you wish to have cached appear in a User Control. One way to specify that the contents of a User Control should be cached is to supply an OutputCache directive at the top of the User Control. That's it! The content inside the User Control will now be cached for the specified period, while the ASP.NET Web page that contains the User Control will continue to serve dynamic content. (Note that for this you should not place an OutputCache directive in the ASP.NET Web page that contains the User Control - just inside of the User Control.) Data Caching In simple terms data caching is storing data in memory for quick access. Typically information that is costly to obtain (in terms of performance) is stored in the cache. One of the more common items stored in a cache in a Web application environment is commonly displayed database values; by caching such information, rather than relying on repeated database calls, the demand on the Web server and database server's system resources are decreased and the Web application's

scalability increased. As Microsoft eloquently puts it, "Caching is a technique widely used in computing to increase performance by keeping frequently accessed or expensive data in memory. In the context of a Web application, caching is used to retain pages or data across HTTP requests and reuse them without the expense of recreating them." Using Data Caching The .NET data caching API is comprised of the two classes in the System.Web.Caching namespace. The first class, Cache, is the class we'll be using to add and remove items from the data cache. The second class, CacheDependency, is used when assigning a cache dependency to an item in the data cache. To add an item to the cache you can simply do: Cache["key"] = value; // In C# The above code adds the item value to the data cache with the key “key”. The key is used to reference the item at some later point. That is, in another ASP.NET Web page we can extract the value inserted above by using: value = Cache("key") - or value = Cache.Get("key") To explicitly remove an item from the data cache you can use the Remove method, specifying the key of the cache item you want removed: Cache.Remove("key") Inserting an Item into the Cache Inserting an item into the data cache is as simple as saying Cache["key"] = value. Items can also be inserted into the cache using the Insert method, which allows for more powerful semantics on how the item in the cache should be handled. Specifically, the Insert method has four overloaded forms, as shown below: 1. Insert(key as String, value as Object) - Inserts the object value into the cache, giving the item the key name key. This is semantically equivalent to using Cache("key") = value. 2. Insert(key as String, value as Object, dependencies as CacheDependency) - Inserts the object value into the cache with key name key and dependencies specified by the dependencies parameter. We'll discuss cache dependencies shortly. 3. Insert(key as String, value as Object, dependencies as CacheDependency, absoluteExpiration as DateTime, slidingExpiration as TimeSpan) - Inserts the object value into the cache with key name key, dependencies dependencies, and (time-based) expiration policies. Expiration policies, as we'll discuss soon, specify when the item should be evicted from the cache. 4. Insert(key as String, value as Object, dependencies as CacheDependency, absoluteExpiration as DateTime, slidingExpiration as TimeSpan, priority as CacheItemPriority, onRemoveCallBack as CacheItemRemovedCallback) - Inserts the object value into the cache with key name key, dependencies dependencies, (time-based) expiration policies, a cache priority, and a callback delegate. The priority specifies how important it is for the cache item to remain in the cache. That is, items with a lower priority will be evicted from the cache before items with a higher priority. The callback delegate provides a means for you to create your own function that is automatically called when the item is evicted from the cache. The above list of the various forms of the Insert method may look quite daunting. Most often you'll likely use either form 1, 2, or 3. Let's take a moment to discuss the CacheDependency and absolute and sliding time parameters. Recall that information stored in the data cache is being stored on the Web server's memory. In a perfect world, when an item is added to the cache using Insert(key, value) or Cache("key") = value, the item will remain in the cache forever. Unfortunately this is not plausible in the real

world. If the computer the Web server runs on is rebooted, or shuts off, for example, the cache will be lost. Even if the Web server machine is running, you may lose items from the cache. To see why, imagine that your Web server has allocated one MB of memory for storing items in the data cache. Now, imaging that you've added a number of items to the data cache such that you've used exactly 1 MB of memory. Great. Now, what happens when you add another item to the data cache? In order for the new item to "fit," the data cache needs to make room for it by removing an existing item. The existing item that is chosen to be removed is said to be evicted. There may be times when you don't want an item to exist in the cache indefinitely. For example, say that you were displaying an XML file in an ASP.NET DataGrid. Rather than load the XML file into a DataSet and bind the DataSet to the DataGrid each page view, you may opt to cache the DataSet in the data cache. This option would work great until the XML file was altered; at that point, if you were still displaying the cached DataSet the user would be seeing stale information. To overcome this problem, you can add the DataSet to the data cache, but specify that the XML file it represents is a cache dependency. By setting this file as a cache dependency, when the file changes the DataSet will be automatically evicted from the cache. That means the next time the DataSet is attempted to be read from the cache, it will not be found (since it has been evicted) and will be recreated by repopulating the DataSet from the XML file. This is desired since the XML file has changed since the DataSet was last cached. In order to insert an item with a cache dependency, you can do: Cache.Insert("key", myDataSet, New CacheDependency(Server.MapPath("data.xml"))) If you wish to have the cache item evicted from the cache in an absolute time, say, five minutes from when it was inserted into the cache, you can use the third form of the Insert method, whose fourth parameter expects a DateTime value specifying the absolute time. The following code illustrates how to add an item to the cache that will expire five minutes from when it was added and has no cache dependencies: Cache.Insert("key", value, Nothing, DateTime.Now.AddMinutes(5), TimeSpan.Zero) In C# you would use null instead of Nothing to signify that you do not want a cache dependency. Note that since we do not want to specify sliding time expiration, we set the last parameter to TimeSpan.Zero. Whereas an absolute time specifies that the item should be evicted from the cache at a specific time, the sliding time eviction parameter specifies that the cache item should be evicted if it is not referenced in a certain timespan. That is, if we set the timespan parameter to, say, TimeSpan.FromSeconds(30), the cache item will be evicted if it is not referenced within 30 seconds. If it is referenced within 30 seconds, it will be evicted if it's not referenced in another 30 seconds from when it was last referenced, and so on. An example of this would be: Cache.Insert("key", value, Nothing, DateTime.Now, TimeSpan.FromSeconds(30), TimeSpan.Zero) Note that when using the sliding time expiration parameter, the absolute expiration parameter value does not matter. That is, it is automatically set to DateTime.Now and has the sliding time added to it to determine the absolute time the cache item should expire. Of course, if the item is referenced within that time period, the calculation is redone and the absolute expiration time is reset. Before we move on to some examples, let's take a quick look at the CacheItemRemovedCallback delegate. Recall that you can set this in the fourth overloaded form of the Insert method. The CacheItemRemovedCallback specifies a function that is called when the item has been evicted from the cache. To use the CacheItemRemovedCallback you need to first create a function that has the definition: Sub CallbackFunction(String, Object, CacheItemRemovedReason) The CacheItemRemovedReason is an enumeration that explains why the item was removed from the cache. Its entries include: 1. DependencyChanged - the item was removed because its cache dependency was changed.

2. Expired - the item was removed because it expired (either by absolute or sliding time expiration). 3. Removed - the item was explicitly removed via the Remove method. 4. Underused - the item was evicted by the cache because the system needed to free up memory. To add a CacheItemRemovedCallback function to an added cache item you will need to create the appropriate function and a delegate variable that is wired up to the function, as shown below: 'You would use onCacheRemove as the input parameter for the 'CacheItemRemovedCallback parameter in the fourth form of the Insert method Dim onCacheRemove As CacheItemRemovedCallback OnCacheRemove = New CacheItemRemoved(AddressOf Me.CheckCallback) ' Now, create the function Sub CheckCallback (str As String, obj As Object, reason As CacheItemRemovedReason) Response.Write ("Cache was removed because : " & reason) End Sub

Related Documents

Caching
November 2019 47
Disk Caching
October 2019 53
Eye-caching
July 2020 30
Caching Asp.net
November 2019 42
Caching Tutorial
December 2019 19