Web part caching options, how to choose

I don’t think there is a default answer to which caching technique you should use for your custom web parts. However it is important to understand the differences between using the ASP .Net cache object, the Web Part cache memory and database stores and the Caching Application Block found in the Enterprise Library.

 

There is plenty of documentation on the asp .net cache object so I don’t want to go into too much detail. In summary:

  1. Allows you store objects in memory

  2. When the web application is recycled the entire cache is lost

  3. When items are added they can have an expiration policy based on time (a sliding window if needed) and/or dependencies on other objects e.g. if a file changes on disk, then the cache item becomes invalid

  4. Items are removed from cache when they expire or if memory pressures on the machine mean that items must be purged from the cache. ASP .Net will then remove items based on their priority, even if they haven’t expired.

  5. A web part is really just an ASP .Net server control and hence there is no reason why you cannot implement caching in the control like you would any other server control. Either caching objects used by the control or the html rendered by the control. There is nothing web part specific in this scenario. One advantage of using this model is that multiple instances of your control can share the same cache, for example on 200 web part pages you have the same web part with the same data irrespective of the user viewing it. Here you would like to cache the data only once, not 200 times or even more if you do it on a per user basis. Also, you are using the ASP .Net cache which is tried, tested and …and works!

If you choose to use the built in caching functionality of the web part framework you have the option of storing the cache in memory or in SQL Server. This is designed to be configurable, i.e. changing an option in web.config will change the store for **ALL** web parts for that web application. In some way you could say that this is something that an administrator can change at any stage, however the reality is that this is not the case.

Web part cache – in memory:

  1. Actually this just uses the ASP .Net cache object.

  2. Items can be cached per user or per web part. In other words using this will not allow multiple instances of a web part to share the same cache, if you want this you must use ASP .net cache object directly or the caching app block. However, if you don’t want this type of uniqueness then this is great option.

  3. When items are added to the cache the web part framework adds extra text to the cache item key so that it will make the key unique for either the user, or the web part instance.

Web part cache – in SQL Server

  1. What happens here is that the object you choose to cache is serialised with the web part into the database, along with the rest of the web part properties. This is obviously not seen by the developer.

  2. You object that you cache must be serialize-able. Obviously! And must be marked as such otherwise the web part framework will not attempt to write it into the DB.

  3. Once again items can be cached per user or per instance of the web part, the same as the web part in memory option.

  4. There are a couple of really good reasons why you might choose to do this. Firstly, because the cached content is the database all the web servers in the farm share the same cache and application recycle won’t remove your cached data. Unlike the asp .net cache, if a user is load-balanced between web server the user will see the same cached data. Secondly, you probably have more database storage capacity than memory.

  5. Obviously this will be slower that an in-memory cache. How much really depends, you will need to do the appropriate testing. As mentioned earlier the downside of the choosing to cache web part data in SQL or in memory is that it applies to all web parts, therefore if you do this, you could have every web part cache living in the DB.

Caching application block

  1. Developed by PAG group at Microsoft and all source code is made available to you. You can change source code as needed, however for this discussion I am assuming this has not been done.

  2. In some ways this is similar to the ASP .Net cache object, however it has been designed to work in any .Net application not just web apps.

  3. It stores all cache items in a hashtable, which will be lost if the application recycles. This is where a backing store could be used.

  4. If a backing store has been configured then every time an item is added to the hashtable it is also added to the backing store e.g. a SQL Server database table. If the application recycles, the hashtable is lost. When the application starts the hashtable is pre-populated with items from the backing store. The backing store is not used as cache store so that many web server can share the same cache; the backing store is there to recover cached data when an application recycles.

  5. You get advanced time expiration policies e.g. when an item is added to the cache you can specify that is expires on Monday at 11pm. More info on this can be found in the docs for the block.

  6. You have control over the configuration of cache scavenging e.g. maximum number of items allowed in the cache, when items are scavenged etc

  7. You can have multiple caches in one application with different settings e.g. one may have a backing store and the other may not.

  8. Like using the ASP .Net cache directly, your web part could use this as the cache store.

  9. In general I have not found this caching application block to be useful for web parts. If I was developing a smart client it would be something that I would look at.

Idea: have a configuration property on the web part that dictates where the cache will be stored, either the ASP .Net cache directly or using the web part cache framework. This means that you can have control over which web part items are stored in memory and which items are stored in the database.

 

Also, there are many other options that you may come up with e.g. if using the smart part and asp .net user controls, then you could use asp .net output caching. Let me know your thoughts.

If you want more specifics, give me a shout.