1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 113 pps

10 128 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Nội dung

Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1079 Chapter 23: Caching The HttpCachePolicy class gives you an object model for managing client-side state that insulates you from adding HTTP headers yourself. Add the lines from Listing 23-3 to your Page_Load to influence the Response’s headers and the caching behavior of the browser. This listing tells the browser not to cache this Response in memory nor store it on disk. It also directs the Response to expire immediately. Listing 23-3: Using HTTP Headers to force the browser not to cache on the client-side VB Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Response.Cache.SetCacheability(HttpCacheability.NoCache) Response.Cache.SetNoStore() Response.Cache.SetExpires(DateTime.MinValue) Response.Write(DateTime.Now.ToLongTimeString()) End Sub C# protected void Page_Load(object sender, EventArgs e) { Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetExpires(DateTime.MinValue); Response.Write(DateTime.Now.ToLongTimeString()); } Figure 23-3 1079 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1080 Chapter 23: Caching Compare the results of running Listing 23-3 in the before Figure 23-2 and then in the after Figure 23-3. Two new HTTP headers have been injected directing the client’s browser and the Cache-Control Header has changed to no-cache, no-store . The Output Caching HttpModule will respect these HTTP headers, so sending no-cache , no store to the browser also advises the HttpModule to record the response as a cache miss. If your ASP.NET application contains a considerable number of relatively static or non–time-sensitive pages, consider what your client-side caching strategy is. It’s better to take advantage of the disk space and the memory of your users’ powerful client machines rather than burdening your server’s limited resources. Caching Programmatically Output Caching is a very declarative business. UserControls and Pages can be marked up with Output- Cache directives and dramatically change the behavior of your site. Declarative caching controls the life cycle of HTML markup, but ASP.NET also includes deep imperative programmatic support for caching objects. Data Caching Using the Cache Object Another method of caching is to use the Cache object to start caching specific data items for later use on a particular page or group of pages. The Cache object enables you to store everything from simple name/value pairs to more complex objects such as datasets and entire .aspx pages. Although this is quite similar to Session state, the Cache object is shared by all users of the particular web server’s app domain that is hosting this application. So if you put a particular item in the Cache , all users will be able to see that object. This may not work as expected in a server farm scenario since you can’t be assured of which server the user will hit next, and even if there’s only one server involved there may be more than one app domain running this application. Also, the server is free to invalidate any cached item at any time if it needs to reclaim some of the memory. You use the Cache object in the following fashion: VB Cache("WhatINeedToStore") = myDataSet C# Cache["WhatINeedToStore"] = myDataSet; After an item is in the cache, you can retrieve it later as shown here: VB Dim ds As New DataSet ds = CType(Cache("WhatINeedToStore"), DataSet) C# DataSet ds = new DataSet(); ds = (DataSet)Cache["WhatINeedToStore"]; 1080 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1081 Chapter 23: Caching Using the Cache object is an outstanding way to cache your pages and is, in fact, what the OutputCache directive uses under the covers. This small fragment shows the simplest use of the Cache object. Simply put an object reference in it. However, the real power of the Cache object comes with its capability to invalidate itself. That’s where cache dependencies come in. You must always follow the pattern of testing to see if an item is in the Cache, and if not you need to do whatever processing is necessary to re-create the object. Once re-created you can insert it back into the Cache to become available for the next request. Controlling the ASP.NET Cache Ordinarily the default parameters set by ASP.NET for the caching subsystem are appropriate for general use. They are configurable, however, within the machine.config or web.config. These options let you make changes like preventing cached items from expiring when the system is under memory pressure, or turning off item expiration completely. You can set the maximize size the application’s private bytes before the cache begins to flush items. < system.web > < cache disableMemoryCollection="false" disableExpiration="false" privateBytesLimit="0" percentagePhysicalMemoryUsedLimit="90" privateBytesPollTime="00:02:00" / > snip I encourage you to leave the default values as they are unless you’ve done formal profiling of your application and understand how it utilizes the Cache. More detail on this section can be found on MSDN here: http://msdn2.microsoft.com/en-us/library/ms228248.aspx . Cache Dependencies Using the Cache object, you can store and also invalidate items in the cache based on several different dependencies. In ASP.NET 1.0/1.1, the only possible dependencies were the following: ❑ File-based dependencies ❑ Key-based dependencies ❑ Time-based dependencies When inserting items into the cache using the Cache object, you set the dependencies with the Insert method, as shown in the following example: Cache.Insert("DSN", connectionString, _ New CacheDependency(Server.MapPath("myconfig.xml"))) By using a dependency when the item being referenced changes, you remove the cache for that item from memory. 1081 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1082 Chapter 23: Caching Cache Dependencies were improved in ASP.NET 2.0 with the addition of the AggregateCacheDepen- dency class, the newly extendable CacheDependency class, and the capability to create your own custom CacheDependency classes. These three things are discussed in the following sections. The AggregateCacheDependency Class The AggregateCacheDependency class is like the CacheDependency class but it enables you to create an association connecting an item in the cache with many disparate dependencies of different types. For example, if you have a cached data item that is built from XML from a file and you also have information from a SQL database table, you can create an AggregateCacheDependency with inserted CacheDependency objects for each subdependency. To do this, you call Cache.Insert and add the A ggregateCacheDependency instance. For example: Dim agg as new AggregateCacheDependency() agg.Insert(New CacheDependency(Server.MapPath("myconfig.xml"))) agg.Insert(New SqlCacheDependency("Northwind", "Customers")) Cache.Insert("DSN", connectionString, agg) Note that AggregateCacheDependency is meant to be used with different kinds of CacheDependency classes. If you simply want to associate one cached item with multiple files, use an overload of CacheDe- pendency ,asinthisexample: VB Cache.Insert("DSN", yourObject, _ New System.Web.Caching.CacheDependency( _ New String() _ {_ Server.MapPath("foo.xml"), _ Server.MapPath("bar.xml") _ }_ )_ ) C# Cache.Insert("DSN", yourObject, new System.Web.Caching.CacheDependency( new string[] { Server.MapPath("foo.xml"), Server.MapPath("bar.xml") } ) ); The AggregateCacheDependency class is made possible by the new support for extending the p reviously sealed CacheDependency class. You can use this innovation to create your own custom CacheDependency . The Unsealed CacheDependency Class A big change in caching in ASP.NET 2.0 was that the CacheDependency class has been refactored and unsealed (or made overrideable). This allows us tocreate classes that inherit from the CacheDependency 1082 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1083 Chapter 23: Caching class and create more elaborate dependencies that are not limited to the Time , Key ,or File dependencies. When you create your own cache dependencies, you have the option to add procedures for such things as Web services data, only-at-midnight dependencies, or textual string changes within a file. The depen- dencies you create are limited only by your imagination. The unsealing of the CacheDependency class puts you in the driver’s seat to let you decide when items in the Cache need to be invalidated. Along with the unsealing of the CacheDependency class, the ASP.NET team has also built a SQL Server cache dependency — SqlCacheDependency . A SQL cache dependency was the caching feature most requested by ASP.NET 1.0/1.1 developers. When a cache becomes invalid because a table changes within the underlying SQL Server, you now know it immediately. Because CacheDependency is now unsealed, you can derive your own custom Cache Dependencies; that’s what you do in the next section. Creating Custom Cache Dependencies ASP.NET has time-based, file-based, and SQL-based CacheDependency support. You might ask yourself why you would write your own CacheDependency . Here are a few ideas: ❑ Invalidate the cache from the results of an Active Directory lookup query ❑ Invalidate the cache upon arrival of an MSMQ or MQSeries message ❑ Create an Oracle-specific CacheDependency ❑ Invalidate the cache using data reported from an XML Web service ❑ Update the cache with new data from a Stock Price service The new version of the CacheDependency class, while introducing no breaking changes to existing ASP.NET 1.1 code, exposes three new members and a constructor overload that developers can use: ❑ GetUniqueID : When overridden, enables you to return a unique identifier for a custom cache dependency to the caller. ❑ DependencyDispose : Used for disposing of resources used by the custom cache dependency class. When you create a custom cache dependency, you are required to implement this method. ❑ NotifyDependencyChanged : Called to cause expiration of the cache item dependent on the cus- tom cache dependency instance. ❑ New Public Constructor. Listing 23-4 creates a new RssCacheDependency that invalidates a cache key if an RSS (Rich Site Summary) XML Document has changed. Listing 23-4: Creating an RssCacheDependency class VB Imports System Imports System.Web 1083 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1084 Chapter 23: Caching Imports System.Threading Imports System.Web.Caching Imports System.Xml Public Class RssCacheDependency Inherits CacheDependency Dim backgroundThread As Timer Dim howOften As Integer = 900 Dim RSS As XmlDocument Dim RSSUrl As String Public Sub New(ByVal URL As String, ByVal polling As Integer) howOften = polling RSSUrl = URL RSS = RetrieveRSS(RSSUrl) If backgroundThread Is Nothing Then backgroundThread = New Timer( _ New TimerCallback(AddressOf CheckDependencyCallback), _ Me, (howOften * 1000), (howOften * 1000)) End If End Sub Function RetrieveRSS(ByVal URL As String) As XmlDocument Dim retVal As New XmlDocument retVal.Load(URL) Return retVal End Function Public Sub CheckDependencyCallback(ByVal Sender As Object) Dim CacheDepends As RssCacheDependency = _ CType(Sender, RssCacheDependency) Dim NewRSS As XmlDocument = RetrieveRSS(RSSUrl) If Not NewRSS.OuterXml = RSS.OuterXml Then CacheDepends.NotifyDependencyChanged(CacheDepends, EventArgs.Empty) End If End Sub Protected Overrides Sub DependencyDispose() backgroundThread = Nothing MyBase.DependencyDispose() End Sub Public ReadOnly Property Document() As XmlDocument Get Return RSS End Get End Property End Class C# using System; using System.Web; using System.Threading; using System.Web.Caching; using System.Xml; 1084 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1085 Chapter 23: Caching public class RssCacheDependency : CacheDependency { Timer backgroundThread; int howOften = 900; XmlDocument RSS; string RSSUrl; public RssCacheDependency(string URL, int polling) { howOften = polling; RSSUrl = URL; RSS = RetrieveRSS(RSSUrl); if (backgroundThread == null) { backgroundThread = new Timer( new TimerCallback(CheckDependencyCallback), this, (howOften * 1000), (howOften * 1000)); } } public XmlDocument RetrieveRSS(string URL) { XmlDocument retVal = new XmlDocument(); retVal.Load(URL); return retVal; } public void CheckDependencyCallback(object sender) { RssCacheDependency CacheDepends = sender as RssCacheDependency; XmlDocument NewRSS = RetrieveRSS(RSSUrl); if (NewRSS.OuterXml != RSS.OuterXml) { CacheDepends.NotifyDependencyChanged(CacheDepends, EventArgs.Empty); } } override protected void DependencyDispose() { backgroundThread = null; base.DependencyDispose(); } public XmlDocument Document { get { return RSS; } } } CreateanewWebsiteandputthe RssCacheDependency class in a /Code folder. Create a default.aspx and drag t wo text boxes, a label, and a button o nto the HTML Design view. Execute the Web site and enter an RSS URL for a blog (like mine at www.hanselman.com/blog/SyndicationService.asmx/ GetRss ), and click the button. The program checks the Cache object using the URL itself as a key. If the 1085 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1086 Chapter 23: Caching XmlDocument containing RSS doesn’t exist in the cache, a new RssCacheDependency is created with a 10-minute (600-second) timeout. The XmlDocument is then cached, and all future requests within the next 10 minutes to this page retrieve the RSS XmlDocument from the cache. Next, your new RssCacheDependency class from Listing 23-4 is illustrated in the following fragment. The RssCacheDependency is created and passed into the call to Cache.Insert .The Cache object handles the lifetime and calling of the methods of the RssCacheDependency instance: VB < %@ Page Language="VB" ValidateRequest="false" % > < html > < head runat="server" > < title > Custom Cache Dependency Example < /title > < /head > < body > < form runat="server" > RSS URL: < asp:TextBox ID="TextBox1" Runat="server"/ > < asp:Button ID="Button1" onclick="Button1_Click" Runat="server" Text="Get RSS" / > Cached: < asp:Label ID="Label2" Runat="server" >< /asp:Label >< br / > RSS: < br / > < asp:TextBox ID="TextBox2" Runat="server" TextMode="MultiLine" Width="800px" Height="300px" >< /asp:TextBox > < /form > < /body > < /html > < script runat="server" > Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Dim RSSUrl As String = TextBox1.Text Label2.Text = "Loaded From Cache" If Cache(TextBox1.Text) Is Nothing Then Label2.Text = "Loaded Fresh" Dim itDepends As New RssCacheDependency(RSSUrl, 600) Cache.Insert(RSSUrl, itDepends.Document, itDepends) End If TextBox2.Text = CType(Cache(TextBox1.Text), _ System.Xml.XmlDocument).OuterXml End Sub < /script > C# < %@ Page Language="C#" ValidateRequest="false" % > < script runat="server" > void Button1_Click(object sender, System.EventArgs e) { string RSSUrl = TextBox1.Text; Label2.Text = "Loaded From Cache"; if (Cache[TextBox1.Text] == null) { Label2.Text = "Loaded Fresh"; RssCacheDependency itDepends = new RssCacheDependency(RSSUrl, 600); Cache.Insert(RSSUrl, itDepends.Document, itDepends); } 1086 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1087 Chapter 23: Caching TextBox2.Text = ((System.Xml.XmlDocument)Cache[TextBox1.Text]).OuterXml; } < /script > The RssCacheDependency class creates a Timer background thread to poll for changes in the RSS feed. If it detects changes, the RssCacheDependency notifies the caching subsystem with the NotifyDependency- Changed event. The cached value with that key clears, and the next page view forces a reload of the requested RSS from the specified feed. Using the SQL Server Cache Dependency To utilize the SQL Server Cache Dependency feature in ASP.NET, you must perform a one-time setup of your SQL Server database. To set up your SQL Server, use the aspnet_regsql.exe tool found at C: \ Windows \ MicroSoft.NET \ Framework \ v2.0.50727/ . This tool makes the necessary modifications to SQL Server so that you can start working with the new SQL cache invalidation features. Follow these steps when using the new SQL Server Cache Dependency features: 1. Enable your database for SQL Cache Dependency support. 2. Enable a table or tables for SQL Cache Dependency support. 3. Include SQL connection string details in the ASP.NET application’s web.config . 4. Utilize the SQL Cache Dependency features in one of the following ways: ❑ Programmatically create a SqlCacheDependency object in code. ❑ Add a SqlDependency attribute to an OutputCache directive. ❑ Add a SqlCacheDependency instance to the Response object via Response.AddCache- Dependency . This section explains all the steps required and the operations available to you. To start, you need to get at the aspnet_regsql.exe tool. Open up the Visual Studio Command Prompt by choosing Start ➪ All Programs➪Microsoft Visual Studio 2008 ➪ Visual Studio Tools ➪ Visual Studio Command Prompt from the Windows Start menu. After the prompt launches, type this command: aspnet_regsql.exe -? This code outputs the help command list for this command-line tool, as shown in the following: SQL CACHE DEPENDENCY OPTIONS -d < database > Database name for use with SQL cache dependency. The database can optionally be specified using the connection string with the -c option instead. (Required) -ed Enable a database for SQL cache dependency. 1087 Evjen c23.tex V2 - 01/28/2008 3:38pm Page 1088 Chapter 23: Caching -dd Disable a database for SQL cache dependency. -et Enable a table for SQL cache dependency. Requires -t option. -dt Disable a table for SQL cache dependency. Requires -t option. -t < table > Name of the table to enable or disable for SQL cache dependency. Requires -et or -dt option. -lt List all tables enabled for SQL cache dependency. The following sections show you how to use some of these commands. Enabling Databases for SQL Server Cache Invalidation To use SQL Server cache invalidation with SQL Server 7 or 2000, begin with two steps. The first step enables the appropriate database. In the second step, you enable the tables that you want to work with. You must perform both steps for this process to work. If you want to enable your databases for SQL cache invalidation and you are working on the computer where the SQL Server instance is located, you can use the following construct. If your SQL instance is on another computer, change localhost in this example to the name of the remote machine. aspnet_regsql.exe -S localhost -U sa -P password -d Northwind –ed This produces something similar to the following output: Enabling the database for SQL cache dependency. Finished. From this command prompt, you can see that we simply enabled the Northwind database (the sample database that comes with SQL Server) for SQL cache invalidation. The name of the SQL machine was passed in with -S , the username with -U , the database with -d , and most importantly, the command to enable SQL cache invalidation was -ed . Now that you have enabled the database for SQL cache invalidation, you can enable one or more tables contained within the Northwind database. Enabling Tables for SQL Server Cache Invalidation You enable more tables by using the following command: aspnet_regsql.exe -S localhost -U sa -P password -d Northwind -t Customers –et aspnet_regsql.exe -S localhost -U sa -P password -d Northwind -t Products –et You can see that this command is not much different from the one for enabling the database, except for the extra -t Customers entry and the use of -et to enable the table rather than -ed to enable a database. Customers is the name of the table that is enabled in this case. 1088 . e) { Response.Cache.SetCacheability(HttpCacheability.NoCache); Response.Cache.SetNoStore(); Response.Cache.SetExpires(DateTime.MinValue); Response.Write(DateTime.Now.ToLongTimeString()); } Figure 23- 3 1079 Evjen c 23. tex V2 - 01/28/2008 3: 38pm Page 1080 Chapter 23: Caching Compare the results of running Listing 23- 3 in. (DataSet)Cache["WhatINeedToStore"]; 1080 Evjen c 23. tex V2 - 01/28/2008 3: 38pm Page 1081 Chapter 23: Caching Using the Cache object is an outstanding way to cache your pages and is, in fact, what. System.Threading; using System.Web.Caching; using System.Xml; 1084 Evjen c 23. tex V2 - 01/28/2008 3: 38pm Page 10 85 Chapter 23: Caching public class RssCacheDependency : CacheDependency { Timer backgroundThread; int

Ngày đăng: 05/07/2014, 19:20