There have been a couple of posts published recently about caching data within web parts.
http://blog.thekid.me.uk/archive/2008/09/23/sharepoint-caching-and-cachedependency.aspx
http://www.zimmergren.net/archive/2008/10/07/web-part-caching-%E2%80%93-a-simple-approach.aspx
They are great articles and big shout goes out to Vince and Tobias for doing them. In this post I wanted to look at a problem I faced recently using caching within Web Parts. As you all may or may not be aware I have been working on a personal web part development project for a while now. The purpose of this web part is very similar to the work that Vince has been doing with the CKS:EBE and now the ARF. The web part simply talks to views of a list anywhere within a site collection and renders the contents in XML. Using custom XSL Styles, CSS and Images it can be rendered in any way you wish. Most recently I have Ajax enabled it so other controls can be used within the XSL, I will be posting about this in the future. So the web part itself creates an "XMLDocument" and then uses "XmlCompiledTransform" to load the XML and XSL and output to the page. As the web part may well be used multiple times on the page I thought it would be a good idea to cache the data for a specific time so the page refreshes would be faster. To start with I looked into using the "HttpRuntime.Cache" to load the XML and XSL into and then render out to the page. To achieve this I simply modified my code as shown below:
You will notice that I have a parameter for setting the cache clear interval.
So now this is set, I wrapped this up into my web part and compiled and deployed it to the site. All is well; I add the web part and set the value using the tool part options.
My web part renders as expected and works really well.
I can in fact add new items to the list I am using and it will not appear no matter how many times I refresh the page until the cache reset interval has been met. So I am happy as can be however when I add a second web part to the page and configure as normal, when I actually come out of edit mode the web part displays exactly the same as the previous one, this is due to the output line being the following:
So as you can plainly see the cache name will be the same no matter how may web parts are added to the page, hence if I am reading from that it will always be whatever was put into the cache last. So I thought I can just create a unique name for the cache and when I add the web part to the page it will load the correct cache object when needed, but of course you say this won't work because the cache is created on a per Web Application basis. So I was stuck with a dilemma with not being a caching guru and knowing if the "HttpRuntime.Cache" can be chopped up into little compartments and then call the relevant ones when needed. So instead I decided to change the way the caching was working and use the PartCacheRead and PartCacheWrite methods instead. For this I create a new method that could be called within my code:
Notice here that I am checking to see if the cache exists by checking if it is null and then creating the cache object and loading it with the string value that is passed from the XML transform code. Once I added this to the code and redeployed it worked 100% as expected. I know there are probably other ways of doing this maybe even using the "HttpRuntime.Cache" or even using "HttpContext.Cache". As always if you are a caching guru and know of an even better way of making this faster and scalable for lots of web parts on the same page then let me know. Anyway just my thoughts!! J |