Saturday, May 17, 2008

Using AJAX Page Methods to Clear Cache Objects Upon Page Unload

I'm nearing the end of my work on this web page editor:

To eliminate repetitive calls to the SQL Server database, I cached a number of data tables including one that is currently over 4,500 records in size. I've read that the ASP.Net Cache apparently does its own housekeeping, removing objects when it needs more space but I thought it good programming practice to explicitly clear all of the objects I cached when the user was done with the editor. But how to do this?

The idea that came to mind was to somehow tap into the local page's "Unload" event. But how? So I posted this on the excellent ASP.Net forums. None of the responses quite gave me the answer but the two fellows responding, one from Maryland and the other from Indonesia (isn't the Internet a great place!), hinted that there must be a way with AJAX.

Doing some more research, it seemed that AJAX Page Methods were the way to go. There's nobody that I know of that has written more about using them with ASP.Net than Dave Ward on his superb Encosia site. So a little more searching found this article.

I had experimented with Page Methods recently and only through Ward's help did I get the example working. But I really didn't completely understand what was going on. The article I just referred to completely opened up my window of understanding about Page Methods! Here's what I've been able to successfully implement:

In the server-side code of the web page I added this:

[WebMethod]
public static void ClearCache()
{
System.Web.Caching.Cache cache = HttpContext.Current.Cache;
if (cache.Count > 0)
{
cache.Remove("CurrMaxIdx");
cache.Remove("OrigMaxIdx");
cache.Remove("Mines");
cache.Remove("Divisions");
cache.Remove("Contracts");
cache.Remove("Levels");
cache.Remove("Muckpiles");
cache.Remove("MuckpileData");
cache.Remove("Activities");
cache.Remove("MajorTasks");
}
}

Then on the web-page itself (the client-side) I added this:

// Clear the ASP.Net Cache objects before leaving the page.
function clearCache()
{
alert('Clear Cache'); // Debugging only
PageMethods.ClearCache(OnSucceeded, OnFailed);
}

function OnSucceeded(result, userContext, methodName)
{
// In this implementation we will do nothing here
}

function OnFailed(error, userContext, methodName)
{
// In this implementation we will do nothing here
}

// Wire in the above Javascript function to the Page Unload event
window.onunload = clearCache;

That's it! It works absolutely beautifully! One interesting tidbit was that initially I added an 'alert' function in the 'OnSucceeded' event but of course it never displayed because the page itself was being unloaded. But I did check that the server-side code was actually running by going back to the page and stepping through the Page_Load code. The cache objects were definitely no more!

5 comments:

  1. Won't this clear the cache if a postback occurs or the user hits refresh as well?

    ReplyDelete
  2. doesn't work
    it says PageMethods is not defined

    ReplyDelete
  3. ok after addind a scriptmanager with enablepagemethods set tot true it works but paper1337 is right this clears the cache if a postback occurs as well

    ReplyDelete
  4. Got enablepagemethods set to true
    got all the stuff working inside an Update Panel -
    However, it doesn't clear the cache for me at all

    ReplyDelete
  5. Actually - I was getting PageMethods is not defined. (sorry about wording of last post).
    on the webMethod, working in VB, I had made the ClearCache() method Protected.
    once I changed to Public, it worked great - even on PostBacks.
    (I already had the postbacks working anyway)

    ReplyDelete