Output Caching with Dependency in ASP.NET

Output Caching with Dependency in ASP.NET

Introduction

The most performance-critical area in most web applications is the data layer. But many ASP.NET developers don’t realize that you can dramatically reduce the burden on your database and increase the scalability of all your web applications with just a little caching code. 

 ASP.NET has two types of caching. Your applications can and should use both types, because they complement each other: 

  1. Output caching: This is the simplest type of caching. It stores a copy of the final rendered HTML page that is sent to the client. 
  2. Data caching: This is carried out manually in your code. To use data caching, you store important pieces of information that are time-consuming to reconstruct (such as a DataSet retrieved from a database) in the cache.

Here are two caching guidelines to keep you on the right track: 

  1. Cache data (or web pages) that are expensive: In other words, cache information that’s time-consuming to create. The results of a database query or contents of a file are good examples. Not only does it take time to open a database connection or a file, but it can also delay or lock out other users who are trying to do the same thing at the same time. 
  2. Cache data (or web pages) that are used frequently: There’s no point setting aside memory for information that’s never going to be needed again. For example, you might choose not to cache product detail pages, because there are hundreds of different products, each with its own page. But it makes more sense to cache the list of product categories, because that information will be reused to serve many different requests. 

Output Caching

Output Caching allows you to store the output of an entire Page or UserControl via the OutputCache directive. This article covers Programmatic Output Caching with a File Dependency. 

Typical implementations include: 

  • Basic Output Caching  
  • Caching on the Client Side (i.e. personalized data)
  • Specific Query String Parameter 
  • Caching with Several Query String Parameters
  • Fragment Caching (usage of OutputCache directive in a user control)
  • Cache Profiles (web.config settings for group of pages)
<%@ OutputCache Duration="30" 
    VaryByParam="None | ParamName | Param1;Param2 | *" %>

Here is a list of various parameters: 

<%@ OutputCache Duration="#ofseconds"
    Location="Any | Client | Downstream | Server | None | ServerAndClient "
    Shared="True | False"
    VaryByControl="controlname"
    VaryByCustom="browser | customstring"
    VaryByHeader="headers"
    VaryByParam="parametername" 
    VaryByContentEncoding="encodings"
    CacheProfile="cache profile name | ''"
    NoStore="true | false"
    SqlDependency="database/table name pair | CommandNotification"
%>

Data caching allows for caching with dependencies. There are 3 types of dependencies:

  1. files/folder
  2. other cached items
  3. database query via Service Broker notifications 

However, as you can see from the Parameters above, there is no option for File Dependency. Plus, your MS SQL Server instance may not always have the Service Broker enabled. This is the scenario being addressed in this article.  In some cases you may be able to create a solution using VaryByCustom. However, I found that by adding OutputCaching via code rather than Page directive, I could implement it with a File Dependency. Take a look: 

// Programmatic Output Cache 
Response.Cache.SetExpires(DateTime.Now.AddMinutes(30));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetValidUntilExpires(true);
Response.Cache.VaryByParams["PageID"] = true;

string fileDependencyPath = Server.MapPath("~/cmsAssets/DebugPublished.txt");
Response.AddFileDependency(fileDependencyPath);

Example

Recently I worked on a project where I added Fragment Caching to a UserControl that had a CacheDependency applied. This example shows how to:

  • Remove Output Cache on a particular page
  • Use CachePolicy to add a CacheDependency to my OutputCache (closest thing within the OutputCache tag properties would be VaryByCustom="customstring")
  • Dynamically inject a UserControl into a MasterPage (i.e. allows you to conditionally add the control)
  • Use Global.asax Session_Start as a suitable place to expire the cache object that is the dependency object for our OutputCache. This was a suitable place to trigger checking some conditions and Inserting a new cache object (expiring the previous dependency in the process) if suitable. I could have done this somewhere else, such as a explicit website visitor action, or approval of a page in the Content Management System being used.

ControlFile.ascx:

<%@ OutputCache Duration="3600" VaryByParam="PageID" %>

ControlFile.ascx.cs:

protected void Page_Load(object sender, EventArgs e)
{		
	if (Request.RawUrl.ToLower().Contains("custom.aspx"))
	{
		// Programmatic Output Cache - Force Expire 
		// Page.Response.Cache.SetCacheability(HttpCacheability.NoCache);
		HttpResponse.RemoveOutputCacheItem("/custom.aspx");
		
		pages.DataSource = ReportTools.Utils.GetCustomReport();
	}
	else
	{
		// Caching - Expire OutputCache
		this.CachePolicy.Dependency = new System.Web.Caching.CacheDependency(null,new string[] { "PublishHistoryCount" });
		
		pages.DataSource = ReportTools.Utils.GetSlides(ReportTools.Utils.CategoryID); 
	}


	pages.DataBind();
}

InnerContent.master.cs:

protected override void OnInit(EventArgs e)
{
	PartialCachingControl tc = (PartialCachingControl)LoadControl("../../cmsAssets/CustomUserControls/ControlFile.ascx");
	PlaceHolder1_1.Controls.Add(tc);


	base.OnInit(e);
	this.MyPlaceHolders.Add(PlaceHolder1);
}

Global.asax:

void Session_Start(object sender, EventArgs e)
{	  
	if(HttpContext.Current.Cache["PublishHistoryCount"] == null)
	{
		HttpContext.Current.Cache.Insert("PublishHistoryCount", ReportTools.Utils.PublishHistoryCount, null,
			  System.DateTime.MaxValue, System.TimeSpan.Zero,
			  System.Web.Caching.CacheItemPriority.NotRemovable,
			  null);
	}
	else
	{
		int phc = (int)HttpContext.Current.Cache["PublishHistoryCount"];


		if(phc != ReportTools.Utils.PublishHistoryCount)
		{
			HttpContext.Current.Cache.Insert("PublishHistoryCount", ReportTools.Utils.PublishHistoryCount, null,
				  System.DateTime.MaxValue, System.TimeSpan.Zero,
				  System.Web.Caching.CacheItemPriority.NotRemovable,
				  null);
		}
	}
}

Key References 

MSDN:

要查看或添加评论,请登录

Richard Harris的更多文章

  • Using Linux on Windows via WSL

    Using Linux on Windows via WSL

    Contents Overview of Windows Subsystem for Linux Setup (including Windows PowerShell Commands for WSL & Linux Shell…

  • Cloud Computing QuickStart Guide

    Cloud Computing QuickStart Guide

    Overview Cloud computing is on-demand access (via the internet) to computing resources — applications, servers…

    2 条评论
  • Software Development & Technology News (01/08/2021 - 25/11/2021 )

    Software Development & Technology News (01/08/2021 - 25/11/2021 )

    Googling for Software Development- What Developers Search For and What They Find · It Will Never Work in Theory Why…

    1 条评论
  • Software Development & Technology News (09/02/2021 - 31/07/2021)

    Software Development & Technology News (09/02/2021 - 31/07/2021)

    Do business leaders know how to evaluate developer success- - ZDNet Will Artificial Intelligence Be the End of Web…

  • Azure Infrastructure | IaaS Day Recap

    Azure Infrastructure | IaaS Day Recap

    Today (17/11/2021) I attended Microsoft's Azure IaaS Day, which was delivered in partnership with Intel. In case you…

  • Microsoft SQL Server

    Microsoft SQL Server

    Introduction MS SQL Server is a Relational Database Management System (RDBMS) developed by Microsoft. It provides GUI…

    1 条评论
  • Custom Software Development: Project Initiation

    Custom Software Development: Project Initiation

    Need a custom app built? I can make your vision a reality! We'd begin with Requirements Gathering, Planning, and…

  • Software Development Life Cycle (SDLC)

    Software Development Life Cycle (SDLC)

    Overview The Software Development Life Cycle (SDLC) is a systematic process that development teams use to produce…

    2 条评论
  • LinkedIn Learning Paths: Computer Science

    LinkedIn Learning Paths: Computer Science

    In my past article Best of LinkedIn Learning: Computer Science, I reviewed the Courses offered by LinkedIn Learning…

  • Glossary of Database Terms

    Glossary of Database Terms

    Use the terms and definitions below to better understand Relational Database concepts. Actors: An actor is a model…

    1 条评论

社区洞察

其他会员也浏览了