MemoryCache

Data handling is one of the basic implementation issues you will find in nearly every application. And very often the same data will be used multiple times. For example the result of a calculation or the result of a database query should be shown to the user. If you have a multi user application then the same calculation or the same database query may be executed multiple times in a short period of time.

In such cases it will be very inefficient to repeat these time consuming steps every time. It will be better to store the data and use it again if the same calculation or the same database query should be executed. This is a basic implementation topic known as „Caching“.

In C# you will find a very easy to use class to implement such caching functionalities: the MemoryCache class. Within this article I want to give you a short introduction to the functions of the MemoryCache class.

 
MemoryCache

The MemoryCache class manages objects which should be cached. The following sample application will show you the basic features of this cache. The console application contains three functions which should represent the three layers of a real application.

– The Main function represents the graphical layer

– The GetPersons function represents the business layer

– The GetPersonsFromDatabase function represents the data layer

 
To create an easy example no database access is implemented. Instead the function GetPersonsFromDatabase will create a new list with persons. Within the business layer the data should be cached and therefore the database access, represented by function GetPersonsFromDatabase, should only be executed if necessary. The following console application contains this basic implementation of a cache functionality.

static void Main(string[] args)
{
    GetPersons();
    GetPersons();
    GetPersons();

    Console.ReadKey();
}

static List<string> GetPersons()
{
    List<string> persons;

    Console.WriteLine("Get persons from management layer");

    //get default cache
    ObjectCache cache = MemoryCache.Default;       

    //get persons
    persons = (List<string>) cache.Get("Persons");

    //if cache does not contain the persons, create new list and add it to cache
    if (persons == null)
    {
        persons = GetPersonsFromDatabase();

        cache.Add("Persons", persons, new CacheItemPolicy());
    }

    return persons;
}
        
static List<string> GetPersonsFromDatabase()
{
    Console.WriteLine("Get persons from data layer");

    return new List<string>()
    {
        "John Doe",
        "Jane Doe"
    };
}

 
The application creates the following output:

Get persons from business layer

Get persons from data layer

Get persons from business layer

Get persons from business layer

 
The default cache will be used to store the data (line 17). With the Get function, the cached object will be accessed (line 20). If the object does not exist the function will return null. It is also possible to use the function Contains to check whether the object exist in the cache. But according to the Tell don’t Ask Principle it is better to use the Get function directly instead of the Contains and Get functions. If the object does not exist within the cache a new object will be created by calling the database function GetPersonsFromDatabase. Afterwards the result of the function will be stored in the cache (line 27).

 
CacheItemPolicy

The cache functions of the example can also be implemented by using a Dictionary object. In this example the MemoryCache object does not use any additional feature compared to a Dictionary. The really powerful feature of the MemoryCache object can be found in the third parameter of the Add function: the CacheItemPolicy.

By using this policy object it is possible to configure conditions under which the cached object should be discarded. The following policies may be set:

AbsoluteExpiration Set the absolute   lifetime of the object. After this timespan the object will be deleted.

SlidingExpiration Set the lifetime of   an unused object. In contrast to the AbsoluteExpiration   this is a relative timespan. Every access to the object will restart the   expiration timer.

ChangeMonitors The cached object will be deleted if a file or database change occurs.

UpdateCallback Set an events to get notification when an item is removed from cache. The UpdateCallback is called before an item is removed.

RemovedCallback Set an event to get notification when an item is removed from cache. The UpdateCallback is called after an item is removed.

Priority Set the priority of the cache object. It is possible to set Default priority or to set NotRemovable priority. In the second case the object will never be removed from the cache.

 

The following example shows one of the policies: the AbsoluteExpiration policy. The object will be discarded after five seconds. Therefore a new object must be created on the last call of the function GetPersons.

static void Main(string[] args)
{
    GetPersons();
    Thread.Sleep(TimeSpan.FromSeconds(3));
    GetPersons();
    Thread.Sleep(TimeSpan.FromSeconds(3));
    GetPersons();

    Console.ReadKey();
}

static List<string> GetPersons()
{
    List<string> persons;

    Console.WriteLine("Get persons from business layer");

    //get default cache
    ObjectCache cache = MemoryCache.Default;

    //get persons
    persons = (List<string>)cache.Get("Persons");

    //if cache does not contain the persons, create new list and add it to cache
    if (persons == null)
    {
        persons = GetPersonsFromDatabase();

        CacheItemPolicy policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(5);

        cache.Add("Persons", persons, policy);
    }

    return persons;
}

static List<string> GetPersonsFromDatabase()
{
    Console.WriteLine("Get persons from data layer");

    return new List<string>()
    {
        "John Doe",
        "Jane Doe"
    };
}

 
The application creates the following output:

Get persons from business layer

Get persons from data layer

Get persons from business layer

Get persons from business layer

Get persons from data layer

 
Summary

The MemoryCache object offers an easy to use caching mechanism in C#. By using the given features of the CacheItemPolicy it is possible to define expiration conditions for each cached item.

Werbung
Dieser Beitrag wurde unter .NET, C# abgelegt und mit , , , verschlagwortet. Setze ein Lesezeichen auf den Permalink.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s