Timed refresh of Cache data trick

C

Chris Snyder

I have a page that displays real-time data (road sensors updated every
5 minutes), but the query to display the data takes 15-20 seconds (big
table in a DB w/o indexes, not my fault). This is unacceptable, so I
decided to use the Cache with a 5 minute expiration. I retrieved the
data on AppStart in the global.asax but that resulted in a slow first
page hit. I added a callback method for the CacheItemRemovedCallback
event, but sometimes the browser would make a request during the 15-20
seconds it takes to reload the cache and get a null object.

I ended up using an Application scope variable to hold my data (a
DataTable) and the Cache engine to fire the callback that refreshes
the Application variable. It now seems to work perfectly: the
DataTable is always available and the slow database call happens
behind the scenes and does not affect requests. See code below:

public class Global : System.Web.HttpApplication
{
protected static DateTime LastDataCheck;
private static CacheItemRemovedCallback onRemove = null;
private static EventLog myEventLog = null;
private static Cache appCache = null;
private static HttpApplicationState appVar = null;

/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

public void RemovedCallback(string key,
object value, CacheItemRemovedReason r)
{
ReloadData();

}

protected void Application_Start(Object sender, EventArgs e)
{
onRemove = new CacheItemRemovedCallback(this.RemovedCallback);

// Grab the Cache and App references while the Context is valid
appCache = Context.Cache;
appVar = Context.Application;

ReloadData();
}

private void ReloadData()
{
try
{
object myDataTable = DataManager.GetRecentData();

LastDataCheck = DateTime.Now;

// Just put the string "abc" to act as a placeholder in the Cache
appCache.Insert("CachePlaceholder", "abc", null,
LastDataCheck.AddMinutes(4),
TimeSpan.Zero, CacheItemPriority.Low, onRemove);

// Store myDataTable DataTable in the HttpApplicationState variable
appVar["myDataTable"] = myDataTable;
appVar["LastDataCheck"] = LastDataCheck;

myEventLog.WriteEntry("Cache Updated: " +
DateTime.Now.ToString(), EventLogEntryType.Information);
}
catch(Exception e)
{
myEventLog.WriteEntry("Error occured retrieving data: " +
e.Message, EventLogEntryType.Error);

}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top