Object Caching in .NET 4 and CRM

The CRM developer Sir Les told me how he used .NET 4 caching in some plugin code to cache some query data which was used by a plugin.

My first response was

What the heck is caching .NET4?

Quickly followed by

I want to have a look at the code and see how the magic works.

What is Object caching .NET 4?

Object caching is baked into the core .NET files and can be found in the namespace

System.Runtime.Caching

The classes in this namespace provide a way to use caching facilities like those in ASP.NET, but without a dependency on the System.Web assembly.

From a CRM point of view caching was brought in with version .NET 4.0 so this means you can use caching with CRM 2011, CRM 2013 and CRM 2015.

I will add at this point I haven’t really used any other .NET caching but from the link above it seems you could do caching using the System.Web but I don’t really know much about it and it doesn’t seem like it’s a good time to learn about what was but instead we shall learn about what is in

System.Runtime.Caching and the Object caching it offers.

This type of caching is InMemory caching using the object

MemoryCache

This offers a simple way to cache some object in the .NET memory, which sounds like a useful tool for plugins running on the CRM server when using static (ish) data.

The MemoryCache Constructor has some interesting points

MemoryCache Constructor

When this constructor is invoked, configuration settings are first retrieved from application configuration files. If no configuration entries exist in the application configuration file, only the settings provided in config are applied

There is no mechanism to enforce unique names for cache instances. Therefore, it is possible to have multiple cache instances with the same name.

An important point is it won’t stop you adding duplicate keys so you must monitor and keep track of this yourself.

The last class you need to know about is

ObjectCache 

Reading articles about ObjectCache and looking at code examples it seems to be an easy to use and not very complex method to cache objects.  This may mean you might run into problems with creating multiple objects cached with the same name, so I advise some caution.

Lets see the code

In this line, we are obtaining a reference to the default MemoryCache instance. Using the new .NET Caching runtime, you can have multiple MemoryCaches inside a single application.

You need to add this using

using System .Runtime .Caching ;

This line gets a reference to the default MemoryCache instance

ObjectCache Cache = MemoryCache .Default ;

To add something to the cache

const string key = “IncidentMetaData”;

List<string > testData = new List<string> { “Meta1”, “Meta2”, “Meta3” };

Cache.Add (key, objectToCache, DateTime.Now.AddHours(24));

The code has added the List<string> test data into the memory cache with the name “IncidentMetaData”.  From a CRM perspective this is a similar to items in the Attributes collection on an entity.

You can get things out from the cache by doing this

cache.Get(keyText)

The keyText is the name of the cacheObject you want to retrieve, if you wanted to get the example above you would type in “IncidentMetadata”.

There is other functionality which can monitor changes for cached files.

There is other functionality to remove items from the cache.

Cache.Remove(key);

Code to get started

I have only briefly only mentioned the functionality, I would advise you to read this blog and download the sample code and you can use the static class.  This first blog I found the most useful

Object Caching – .NET 4

These other blogs will give you some more reading and examples

System.Runtime.Caching Namespace

How to: Cache Objects Simply using System.Runtime.Caching.MemoryCach

Working with System.Runtime.Caching.MemoryCache

When to use the in memory cache with CRM

Most of the time I don’t think you would need to use this code in CRM plugins because it’s easy to store and retrieve data from CRM using LINQ or QueryExpression queries.

The in memory cache is suitable for queries which return the same data most of the time.

This could be things like

  • Language settings
  • Config file settings
  • Metadata

In the example I am using I am retrieving all the metadata for the incident entity and this data would be retrieve many times in short period of time whilst 100 of records would be imported.  In this scenario it made sense to  cache the data.

Consider this would create a cache on each CRM server because the cache works on server basis.

plugins triggered by importing

if you have plugins which are triggered when importing lots of records, you may benefit from caching some queries.

I thought I would blog about this because it seemed like an interesting tool developers might want to use.  Be aware there could be limitations and gotcha’s I haven’t worked out yet

I certainly wouldn’t overuse this because most queries retrieving records in CRM run quickly, with the majority of plugins performance is not an issue

 

Advertisement

7 thoughts on “Object Caching in .NET 4 and CRM

  1. Scott Durow (@ScottDurow) April 20, 2015 / 9:22 am

    One of those ‘gotchas’ is that this does not fully work for sandboxed plugins due to the isolated nature of the executing plugin host.

    Like

    • Hosk April 20, 2015 / 11:16 am

      Hi Scott

      I hadn’t considered the effects of sandboxed plugins. I tested this on our dev environment where the plugins are of isolation type = sandboxed.

      The caching worked without problems.

      I guess this wouldn’t work on CRM online instances but this worked for plugins on premise

      I haven’t monitored this much yet, so things gotcha’s could still be lurking

      Like

      • Scott Durow (@ScottDurow) April 20, 2015 / 12:33 pm

        You might see the cache working but it’ll be short lived because the process that the sandbox plugin runs within is frequently torn-down/restarted.

        Like

      • Hosk April 21, 2015 / 2:10 pm

        Interesting, this has got me thinking. I thought this object caching worked on a .NET level but if doesn’t then my cached query values will soon be washed away as sandbox processes pop up and down rather quickly.

        Thanks for the reply, more investigation needed by myself

        Like

  2. Paul January 17, 2022 / 3:42 pm

    As Scott mentioned, System.Runtime.Cache doesnt work consistently with 365 online, so is there any preferred caching method in 365 online? I am using paging and currently have to re-fetch 1000’s of records from external http connection for each page!

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.