Click here to Skip to main content
14,693,744 members
Articles » Platforms, Frameworks & Libraries » .NET Framework » General
Posted 8 Apr 2014

Tagged as


56 bookmarked

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

Rate me:
Please Sign up or sign in to vote.
4.80/5 (29 votes)
8 Apr 2014CPOL
This article offers a way to simply the use of System.Runtime.Caching.MemoryCache for caching application objects

Image 1


This article shows how to properly use System.Runtime.Caching.MemoryCache by unifying an inherited Singleton structure.


It is very common for an application to cache objects, whether it is a server side application such as WCF service (Per-Call), a web application (server-side) or even a simple standalone Windows application (WPF/Win-Forms).

.NET 4.0 provides a very simple caching object called System.Runtime.Caching.MemoryCache.

But how do we properly use this object?

From my experience, it is better to unify & simplify these objects into a structured utility that can be used across the application for the following reasons:

  1. Avoids code duplication across the application
  2. MemoryCache configuration is unified and can be easily changed
  3. Ease of access to the use of the object for the less experienced programmers on the team

Caching Provider (Base)

Let's wrap the System.Runtime.Caching.MemoryCache using an abstract base class that contains:

  1. MemoryCache instance
  2. Locking mechanism
  3. Errors log
public abstract class CachingProviderBase
    public CachingProviderBase()

    protected MemoryCache cache = new MemoryCache("CachingProvider");

    static readonly object padlock = new object();

    protected virtual void AddItem(string key, object value)
        lock (padlock)
            cache.Add(key, value, DateTimeOffset.MaxValue);

    protected virtual void RemoveItem(string key)
        lock (padlock)

    protected virtual object GetItem(string key, bool remove)
        lock (padlock)
            var res = cache[key];

            if (res != null)
                if (remove == true)
                WriteToLog("CachingProvider-GetItem: Don't contains key: " + key);

            return res;

    #region Error Logs

    string LogPath = System.Environment.GetEnvironmentVariable("TEMP");

    protected void DeleteLog()
        System.IO.File.Delete(string.Format("{0}\\CachingProvider_Errors.txt", LogPath));

    protected void WriteToLog(string text)
        using (System.IO.TextWriter tw = System.IO.File.AppendText(string.Format("{0}\\CachingProvider_Errors.txt", LogPath)))


Global Caching Provider

Next, I will create an example of a global application cache, which is used for common caching activities of simply caching an object and fetching and removing the object.

public interface IGlobalCachingProvider
    void AddItem(string key, object value);
    object GetItem(string key);

The Global Caching Provider inherits from the CachingProviderBase, and exposes an interfaced singleton:

public class GlobalCachingProvider : CachingProviderBase, IGlobalCachingProvider
    #region Singleton 

    protected GlobalCachingProvider()

    public static GlobalCachingProvider Instance
            return Nested.instance;

    class Nested
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        internal static readonly GlobalCachingProvider instance = new GlobalCachingProvider();


    #region ICachingProvider

    public virtual new void AddItem(string key, object value)
        base.AddItem(key, value);

    public virtual object GetItem(string key)
        return base.GetItem(key, true);//Remove default is true because it's Global Cache!

    public virtual new object GetItem(string key, bool remove)
        return base.GetItem(key, remove);



Using the Code

For the sake of simplicity, I will demonstrate the use of System.Runtime.Caching.MemoryCache by a basic WPF application.

The application is caching a text message and fetching the message only when the presentation object is created. The presentation object is completely disconnected from the object storing the message, and even does not have to exist when the message is being stored.

Image 2

The process is as follows:

Image 3

The code behind is as follows:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
    public MainWindow()

        pesenterCombobox.SelectedIndex = 0;

    private void StoreBtn_Click(object sender, RoutedEventArgs e)
        string text = new TextRange(inputTextBox.Document.ContentStart,

        //Store the message in the cache:
        GlobalCachingProvider.Instance.AddItem("Message", text);

    private void PresentBtn_Click(object sender, RoutedEventArgs e)
        //fetch the message from the cache:
        var message = GlobalCachingProvider.Instance.GetItem("Message") as string;

        switch (pesenterCombobox.SelectedIndex)
            case 0:
            case 1:
                    contentPresenter.Content = new TextBlock() { Text = message };
            case 2:
                    if (message != null)
                        var listbox = new ListBox();
                        var lines = message.Split('\n');
                        foreach (var ln in lines)
                            listbox.Items.Add(new ListViewItem() { Content = ln, Height = 16 });
                        contentPresenter.Content = listbox;

Further Discussion

The idea behind the article is offering a way unify & simplify your code using application utilities. When we are planning an application, we should modularize our code in order to achieve:

  1. Flexibility in case of future changes
  2. Easy maintenance

Modularize code is unified, simple and easy to change, it's also easy to maintain because every module is a small part of the system. Instead of searching for the bug in, say 1,000 lines of code (LOC) you only need to check ~100 LOC.

Modularize application should often be using strong, unified & simplified utilities. For example:

  • ThreadInvoker - enables us to simplify and change the use of threads.
  • LoggerManager - enables us to simplify and change the use of loggers.
  • DataAccessManager - enables us to simplify and change the access to data: sometimes it could be access to Database and sometimes WCF services or both.... and we can change it without touching the business-logic code!
  • Etc.


  • 11 May 2014 - Adding "Further Discussion" section


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Shai Vashdi
Chief Technology Officer GalilCS
Israel Israel
My name is Shai Vashdi and I’m the CTO & Co-Founder of GalilCS.
GalilCS provides industrialized, low-cost IT services (ILCS) to corporations around the globe. We specialize in code modernization projects (VB6 to C# WinForms/HTML5, for example) and code refactoring projects.
Most of my work revolves around the management of these projects and the creation of new tools for refactoring code. As a bonus, I also get to lecture about Microsoft programming languages.
For more information, visit GalilCS.

Comments and Discussions

GeneralMy vote of 2 Pin
Juan José De Arana27-Dec-16 21:50
MemberJuan José De Arana27-Dec-16 21:50 
QuestionInterfaced Singleton ? Pin
Member 103728068-Nov-16 14:54
MemberMember 103728068-Nov-16 14:54 
QuestionHow to invalidate cache data Pin
Tridip Bhattacharjee19-Sep-16 22:48
professionalTridip Bhattacharjee19-Sep-16 22:48 
suppose i have added multiple customer data to cache from sql server. i will design my program in such a way when any customer data will be change in db table then i will get notification and then i want to fire a routine which will remove customer cache data and reload customer again into cache from db table.

or just update those customer data into cache whose data has been changed in db table.

please guide me with sample code that how could i do this.

QuestionHow to add multiple item and get data by filter Pin
Tridip Bhattacharjee19-Sep-16 22:44
professionalTridip Bhattacharjee19-Sep-16 22:44 
Generalmy vote of 5 Pin
Southmountain2-Apr-16 11:34
MemberSouthmountain2-Apr-16 11:34 
GeneralMy vote of 2 Pin
AndrewB-UK21-Jan-15 7:25
MemberAndrewB-UK21-Jan-15 7:25 
SuggestionDistributed Caching using System.Runtime.Caching.ObjectCache Pin
sameer@alachisoft.com28-Dec-14 1:51
Membersameer@alachisoft.com28-Dec-14 1:51 
QuestionWhy are you locking the object? PinPopular
aprajay16-Oct-14 3:01
Memberaprajay16-Oct-14 3:01 
AnswerRe: Why are you locking the object? Pin
Juan José De Arana27-Dec-16 21:48
MemberJuan José De Arana27-Dec-16 21:48 
GeneralMy vote of 5 Pin
Shai Vashdi17-Apr-14 6:13
MemberShai Vashdi17-Apr-14 6:13 
GeneralRe: My vote of 5 Pin
John B Oliver29-Apr-14 12:53
MemberJohn B Oliver29-Apr-14 12:53 
GeneralRe: My vote of 5 Pin
Shai Vashdi29-Apr-14 14:40
MemberShai Vashdi29-Apr-14 14:40 
GeneralRe: My vote of 5 Pin
Nelek11-May-14 7:18
protectorNelek11-May-14 7:18 
GeneralMessage Closed Pin
8-Apr-14 21:17
professionalАslam Iqbal8-Apr-14 21:17 
GeneralRe: My vote of 1 PinPopular
John Brett9-Apr-14 2:22
MemberJohn Brett9-Apr-14 2:22 
GeneralRe: My vote of 1 PinPopular
Paolo Senigagliesi9-Apr-14 2:58
MemberPaolo Senigagliesi9-Apr-14 2:58 
GeneralRe: My vote of 1 Pin
Shai Vashdi9-Apr-14 8:25
MemberShai Vashdi9-Apr-14 8:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.