Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP .NET Web Developer s Guide - Mesbah Ahmed, Chris Garrett

.pdf
Скачиваний:
37
Добавлен:
24.05.2014
Размер:
7.32 Mб
Скачать

280 Chapter 6 • Optimizing Caching Methods

set for this page, it will not be cached. If you refresh this page after the initial load, you will see that the first timer will not change if the cache duration has not been passed, and the second timer is changed to the current time.

Figure 6.9 Fragment Caching Example

As with output caching, fragment caching can be used either through the @ OutputCache directive or programmatically through the HttpCachePolicy class. Fragment caching differs in that it only supports the VaryByParam attribute as well as a new attribute named VaryByControl.The VaryByParam attribute is a required attribute in fragment caching as well. Fragment caching does not support the VaryByHeader nor the VaryByCustom attributes.

The VaryByParam attribute works the same way in fragment caching as it does in output caching. Using this attribute, a separate page can be generated and cached for each argument provided to the user control. Just as in output caching, this capability greatly increases the performance of your page.

The additional attribute provided for fragment caching, the VaryByControl attribute, enables you to control the cache based on controls within the user control.This attribute can be used with the following syntax:

<% @ OutputCache duration="60" VaryByParam="none" VaryByControl="name" %>

www.syngress.com

Optimizing Caching Methods • Chapter 6

281

For example, if you have a control in your application that contains a select box control named “name,” then ASP.NET would cache a separate version of the page each time the value of the select box control changed.

There is one major aspect of fragment caching that must be kept in mind. If a user control is cached, it can no longer be manipulated. Basically, when the user control is cached, the instance for the control is only created on the first request, and not on subsequent requests when the data is pulled from the cache. Because of this, the logic necessary to create the content of a user control should be stored within the control itself, and not within the calling page.This can be done by using the Page_Load event or the Page_PreRender event.This enables you to pass arguments to the control and generate new content based on those arguments.This can be further enhanced by using fragment caching with the

VaryByControl attribute.

Advantages of Using Fragment Caching

The greatest advantage of fragment caching is the ability to cache only portions of a page while generating the remainder of the page dynamically.While this does not provide as much of a performance increase as output caching, it enables you to take advantage of caching in situations when it would previously not be possible to cache the page at all.

A second advantage of fragment caching is the possibility of better use of memory resources.When caching an entire page, all of the data for that page is stored in memory.With fragment caching, only the portions of the page you specify are cached.This advantage is best presented when you have several pages that call a common user control. After the user control is cached on the first request, any subsequent request from any page presents the cached data.This enables you to make the most of your system resources by caching commonly used user controls.

Data Caching

Data caching provides the most granular control of cached data.The data cache is a full-featured cache engine that enables you to store and retrieve data between multiple HTTP requests and multiple sessions within the same application. As with output caching and fragment caching, the cached data and objects are stored in memory, providing fast access to cached information. Another similarity to output caching and fragment caching is that the cache is cleared completely when the application is reset.

www.syngress.com

282 Chapter 6 • Optimizing Caching Methods

There are three different methods that you can use to add data or objects to the cache.They all work in a very similar fashion, but offer different levels of control and usage.The cache method is used for fast and easy access to the data cache. The cache.add and cache.insert methods are used to give you a greater amount of control over the data that you cache. Each of these methods has its uses and we will go into detail on each of them in the sections that follow.Table 6.4 outlines the features of the different caching methods.

Table 6.4 Caching Method Features

 

Stores Data

Dependency

Expiration

Priority

Returns

Method

in Cache

Support

Policy

Settings

Object

 

 

 

 

 

 

cache

X

 

 

 

 

cache.insert

X

X

X

X

 

cache.add

X

X

X

X

X

 

 

 

 

 

 

Using the Cache Method

Microsoft has provided a simple dictionary-style interface for using the data cache. Because of this interface, you can store and retrieve data from the cache as easily as you would store and retrieve data from a dictionary.The syntax for storing data in this cache is as follows:

cache("keyname")=value

Caching data has never been so simple! The retrieval of your data is also a very simple operation. In the following code, we will pull the value from the cache based on the key we specified, and display it.

myvalue=cache("keyname")

if value <> null then

displaydata(myvalue)

end if

This method of caching works very well for providing fast access to your objects. In addition to using the simple dictionary-style method of storing and retrieving simple data, you can also use data caching to store arrays or any other object.This technique is illustrated in Figures 6.10, 6.11, and 6.12.You can find the source code in Figure 6.10 on the CD that accompanies this book as data_cache1.aspx.

www.syngress.com

Optimizing Caching Methods • Chapter 6

283

Figure 6.10 Data Caching Example Code (data_cache1.aspx)

<SCRIPT language="VB" runat=server>

Sub Page_Load(source As Object, e As EventArgs)

dim MyValue as string

MyValue=cache("MyKey")

if MyValue <> nothing then

output.text=MyValue & "<P>This data retrieved from cache" else

Dim stringArray() As string ={"Amy", "Bob", "Chris", "Dave", _ "Eli", "Franklin", "Gerald"}

dim MyString as string

for each MyString in stringArray output.Text=output.Text & MyString & "<br>"

next

cache("MyKey")=output.Text end if

End Sub </SCRIPT> <HTML> <HEAD> </HEAD> <BODY>

<P><asp:label id="output" runat="server"/> </BODY>

</HTML>

Figure 6.11 shows the output of the code sample in Figure 6.10 on the first page request. ASP.NET first checks the cache to see if the key name we specify contains any data. Since at this point it does not, the array is generated and saved to the cache.When the page is viewed a second time, as shown in Figure 6.12, ASP.NET finds the data in cache and displays the cached data as well as the message indicating that the source data is from the cache rather than being generated.

www.syngress.com

284 Chapter 6 • Optimizing Caching Methods

Figure 6.11 Data Caching Example Page 1

Figure 6.12 Data Caching Example Page 2

www.syngress.com

Optimizing Caching Methods • Chapter 6

285

Using the cache.add and cache.insert Methods

In the example code in Figure 6.10, we have used the cache method in the same manner that we would use a dictionary. Using this method, the data remains in cache for the lifetime of the application or until it is explicitly removed from the cache. For greater control over the data we are storing in the cache, we can use two other methods of storing the data.The first is the cache.add method and the second is the cache.insert method.These are very similar, but they do differ, in that the cache.add method returns an object that represents the cached data, and the cache.insert method does not.The code used in the previous section to simply add an object to the cache can be expressed in the following way, using either the cache.add or the cache.insert method. For this example we will use the cache.insert method.

cache.insert("keyname", value)

Using either the cache.add or the cache.insert methods, you have three primary options available to us for the manner in which you can control the cached data. The first option is to base the expiration of a cached object on dependency files, directories, or other cached object keys.The second option is comprised of two different methods of controlling the expiration policy of the cached object based on time.The third option is comprised of two methods of controlling the cached object’s cache priority, and the final option allows a method of obtaining notification when an object is removed from the cache.

Using the Dependency Option

When you have a dependency object set for a cached object, ASP.NET monitors the dependency object for changes.When a change is detected in the dependent object, the cached item with the dependency option expires.The syntax for using the cache.add and cache.insert methods with the dependency option is the same, and for this example we will use the cache.insert method:

cache.insert("keyname", value, New

CacheDependency(Server.Mappath("data.xml")))

There are many ways to put this option to use. For example, if you wish for a cached item to expire when another cached item changes, then set the second cached object to be dependent on the first cached object’s key.

It is also possible to make a cached object dependent on multiple other objects. For example, if you have multiple XML files that your page is pulling

www.syngress.com

286 Chapter 6 • Optimizing Caching Methods

data from, and wish for a cached item to expire when any of the XML files change, you can list these files in an array and make the array your dependent object. An example of this usage is shown in Figure 6.13, and you can locate this code on the CD that accompanies this book as data_cache2.aspx.

Figure 6.13 Data Caching with Multiple Dependencies Code (data_cache2.aspx)

<SCRIPT language="VB" runat=server>

Sub Page_Load(source As Object, e As EventArgs)

dim MyValue as string

MyValue=cache("MyKey")

if MyValue <> nothing then

output.text=MyValue & "<P>This data retrieved from cache" else

Dim StringArray() As string ={"Amy", "Bob", "Chris", "Dave", _ "Eli", "Franklin", "Gerald"}

dim DependentString() as string ={server.mappath _ ("partofmydata.xml"), server.mappath("theotherpart.xml")}

dim MyString as string

for each MyString in StringArray output.Text=output.Text & MyString & "<br>"

next

cache.insert("MyKey", output.text, new _ CacheDependency(DependentString))

end if End Sub </SCRIPT>

<HTML>

<HEAD>

</HEAD>

Continued

www.syngress.com

Optimizing Caching Methods • Chapter 6

287

Figure 6.13 Continued

<BODY>

<P><asp:label id="output" runat="server"/>

</BODY>

</HTML>

Using the Expiration Policy Option

The second caching option sets the expiration policy of the cached object.There are two ways to set the expiration policy.The first is to use an absolute expiration time that sets the cached object to expire at a specific time.The syntax for this statement is as follows:

cache.insert("keyname", value, nothing, _

datetime.now.addminutes(2), timespan.zero)

Even when using just one of the two expiration policy parameters, the other must contain some value. In addition, when using either method, you must set the dependency option to either an object or the nothing object. In the case of the previous code, we have set a timespan of 0 for the second parameter, which effectively disables it.This option is useful when you have a cached object that you want to have refreshed on a regular basis regardless of how many times the cached object has been accessed.

The second expiration policy option is to use a sliding expiration. Using this method, the cached object’s absolute expiration time is increased by value of the sliding expiration parameter. For example, to force the cached object to expire 10 seconds after the last request for the cached object, you could use the following code:

cache.insert("keyname", value, nothing, _

datetime.maxvalue, timespan.fromseconds(10))

Again, as both parameters must contain some value, the absolute expiration parameter has been set to the maxvalue of datetime, which effectively disables the absolute expiration policy.

By using either of these expiration policy options, you can specify the duration of your objects in cache. One caveat to keep in mind is that you must use either an absolute expiration time or a sliding expiration, and ASP.NET does not support the use of both on the same object.Therefore, when setting the expiration policy option, you must use either the timespan.zero or the datetime.maxvalue option.

www.syngress.com

288 Chapter 6 • Optimizing Caching Methods

Using the Priority Options

All of the options for specifying the duration of an object in cache are secondary to ASP.NET’s method of conserving system resources. If your system begins to run low on available memory, the first thing ASP.NET does is begin to clear out the cache until the available system memory reaches a tolerable level. If we had no control over this process, your Web application’s performance could be severely degraded by the loss of critical cached items. Fortunately, ASP.NET provides the ability to control the purging of your cached data.This is set through two options for the cache.add and cache.insert methods.

The first option available is the CacheItemPriority setting.This enables you to set different priorities on cached objects based on how critical the cached data is to the performance of your application.The default value is Normal, and objects are purged in order of lowest priority to highest, leaving high priority objects in the cache for as long as possible.Table 6.5 outlines the different priority settings available for cached objects.

Table 6.5 CacheItemPriority Values

Value

Definition

 

 

NotRemoveable

Cached objects with this priority will never be removed

 

from memory when ASP.NET is purging due to a loss of

 

memory resources. Use this option sparingly, as negative

 

results can occur when ASP.NET is prevented from

 

obtaining needed memory resources due to too many

 

unremovable items in the cache.

High

Objects with this priority level are the last to be purged.

 

ASP.NET will clear all lower-priority objects from memory

 

before clearing objects designated as High priority.

AboveNormal

Objects with this priority level are less likely to be purged

 

than items left at the default level.

Normal

This is the default priority level for cached objects. This

 

value is assigned to all cached objects that do not explic-

 

itly have a priority level designated.

BelowNormal

Objects with this priority level are considered by ASP.NET

 

to be less critical to your application’s performance than

 

normally cached items.

Low

Cached Objects with this priority level are the first to be

 

purged when system memory resources are low.

 

 

www.syngress.com

Optimizing Caching Methods • Chapter 6

289

The second option for setting the priority of cached objects is the CacheItemPriorityDecay setting.This option controls the purging of objects from the cache when they are accessed infrequently.This differs from the CacheItemPriority setting in that it controls the purging of cached objects based on the frequency of their access, as compared to a loss of system memory resources. As with the CacheItemPriority setting, this option has several different values.These values are described in Table 6.6.

Table 6.6 CacheItemPriorityDecay Values

Value

Definition

 

 

Never

Objects set with a decay of Never will not be removed from the

 

cache if accessed infrequently.

Slow

Objects with a decay of Slow are the last to be purged.

Medium

This is the default setting for any objects without a differing

 

explicit setting.

Fast

Objects with this setting are the first to be purged if they are not

 

frequently accessed.

When you choose to explicitly set the priority of a cached object, both priority options must be set as well as setting a CacheItemRemovedCallback delegate, which will be discussed in the next section.To illustrate the use of the priority options, let us assume that we have a dataset to cache.This dataset is very rarely changed and is accessed very often. Although it is large, we have determined that the application would suffer a greater performance loss by not having this data cached than it would by reallocating the memory resources used by the cached dataset. In this scenario, we would want to set the CacheItemPriority value to High and the CacheItemPriorityDecay value to Slow. In addition, we will set the

CacheItemRemovedCallback delegate to OnRemove.We do want the data to be refreshed occasionally, so we will also use an absolute expiration of one hour.

cache.insert("MyKey", mydataset, nothing, _

datetime.now.addminutes(60), timespan.zero, _

CacheItemPriority.High, CacheItemPriorityDecay.Slow, OnRemove)

Using the CacheItemRemovedCallback Delegate

The CacheItemRemovedCallback delegate is a function of the cache that allows the application to be notified when an item is removed from the cache.The

www.syngress.com