When we create applications (web, mobile or dekstop), one of the first things which we need is accurate results and speed. Speed oftens comes with better server, but it also requires a really good to reduce server load. In C# web-applications, we can reduce server load by use of Caching, in of my previous examples, i have explained how we can implement output caching in MVC, now in this article, you will see console application example for In-Memory Cache in .NET and .NET Core, although you can use it in web-applications in similar way.

Why do we need caching?

Our applications often calls same method, again and again and fetch data from database, but sometimes, data doesn't get's changed or updated in database, in that case, we can use caching to reduce database calls and get's same data directly from memory-cache.

There are 3 types of cache available:

  1. In-Memory Cache: Data is cached on server
  2. Persistent in-process Cache: Data is cached in some file or database.
  3. Distributed Cache: Used for a shared cache and multiple processes, like Redis Cache.

We will be learning more details about In-Memory cache, in this article.

MemoryCache in C#

C# memorycache uses namespace "System.Runtime.Caching",so to include it in your current project, you need to imply refer it, by using the following steps:

  1. Go to Solution Explorer
  2. Right-Click on "Reference" and then select "Add Referece", as shown in the below image
  3. Now, search for "System.Runtime.Caching", once you find it, check it and click "Ok"
    in-memorycache-example-in-csharp-console-application-min.png
  4. That's it, now we can use C# memorycache.

Now, that we have included the namespace "System.Runtime.Caching" (can be used with .NET Standard 2.0 or later and .NET framework 4.5 or later) in our application, we can use MemoryCache.

We will be creating, adding cache with easy method.

Creating a new MemoryCache Object

You can create it's object as

 ObjectCache cache = MemoryCache.Default;  

Where MemoryCache.Default = Gets a reference to the default MemoryCache instance.

Adding value in cache

We can use cache.Add(key,value,cacheitempolicy) method to add value, here is a simple example

 cache.Add("CacheName", "Value1", null);
 cache.Add("CacheName2", 0, null);

in the above code, we are adding key, value and null = CacheItemPolicy , basically we are not creating any CacheItemPolicy.

CacheItemPolicy can be used to add cache expiration time, change monitors, update callback etc, here is simple example of CachItemPolicy object, which Absolute Expiration duration

    var cacheItemPolicy = new CacheItemPolicy  
    {  
        AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(60.0)  
    };  

You can use above policy for Cache item as below

            ObjectCache cache = MemoryCache.Default;

            var cacheItemPolicy = new CacheItemPolicy
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(60.0),
                
            };


            cache.Add("CacheName3", "Expires In A Minute", cacheItemPolicy);

We can also add CacheItem object as shown below

            var cacheItem = new CacheItem("fullName", "Vikas Lalwani");
            cache.Add(cacheItem, cacheItemPolicy);

Removing cache item key/value

We can remove any cache key-value object, using it's key and .Remove() method, So suppose if we want to remove cache item with Key Name = "CacheName", simply use the code below

cache.Remove("CacheName");

Getting cache key value

You can use cache.Get("CacheKey") to get value from cache

cache.Get("fullName")

Updating cache key value

You can use .Set() method to update the value of cache item.

 cache.Set("CacheName2", 1, null);

here again in the above code, we have provided cache item key = "CacheName2", 1= value and null= No Cache Item Policy

In updating cache, you can also use cachitem based method

cache.Set(cachItemToUpdate,cachitempolicy)

Getting all objects in Memory cache with value

You can loop through all key-value pair using MemoryCahe.Default object.

 //loop through all key-value pairs and print them
            foreach (var item in cache)
            {
                Console.WriteLine("cache object key-value: "+ item.Key + "-" + item.Value);
            }

Sample Console application using MemoryCache with all operations

using System;
using System.Runtime.Caching;

namespace InMemoryCache
{
    class Program
    {
        static void Main(string[] args)
        {
            ObjectCache cache = MemoryCache.Default;

            //add cache
            cache.Add("CacheName", "Value1", null);
            cache.Add("CacheName2", 0, null);

            // create cache item policy
            var cacheItemPolicy = new CacheItemPolicy
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddSeconds(60.0),
                
            };

            //add cache with cache item policy
            cache.Add("CacheName3", "Expires In A Minute", cacheItemPolicy);

            //add cache with CacheItem object
            var cacheItem = new CacheItem("fullName", "Vikas Lalwani");
            cache.Add(cacheItem, cacheItemPolicy);

            //get cache value and print
            Console.WriteLine("Full Name "+ cache.Get("fullName"));

            //print all cache
            Console.WriteLine("All key-values");
            PrintAllCache(cache);

            //remove cache
            cache.Remove("CacheName");

            //update cache value, from 0 to 1
            cache.Set("CacheName2", 1, null);

            //print all cache key value again to check updates
            Console.WriteLine("All key-values after updates");
            PrintAllCache(cache);
        }

        public static void PrintAllCache(ObjectCache cache)
        {
            //loop through all key-value pairs and print them
            foreach (var item in cache)
            {
                Console.WriteLine("cache object key-value: "+ item.Key + "-" + item.Value);
            }
        }
    }
}

Output:

Full Name Vikas Lalwani
All key-values
cache object key-value: CacheName2-0
cache object key-value: CacheName-Value1
cache object key-value: CacheName3-Expires In A Minute
cache object key-value: fullName-Vikas Lalwani
All key-values after updates
cache object key-value: CacheName2-1
cache object key-value: CacheName3-Expires In A Minute
cache object key-value: fullName-Vikas Lalwani

in-memory-cache-c-sharp-console-application-complete-example-min.png

MemoryCache Example in .NET Core console application

To use it in .NET Core console application, once you finish creating console application in .NET Core/Visual Studio, then you would have to install two NuGet Packages

  1. Microsoft.Extensions.Caching.Memory
  2. System.Runtime.Caching

Console application example in .NET Core using MemoryCache

using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Primitives;
using System;

using System.Threading;

namespace InMemoryNetCore
{
    class Program
    {
        static void Main(string[] args)
        {
            IMemoryCache cache = new MemoryCache(new MemoryCacheOptions());
            object result;
            string key = "KeyName";
      

            // Create / Overwrite
            result = cache.Set(key, "Testing 1");
            result = cache.Set(key, "Update 1");

            // Retrieve, null if not found
            result = cache.Get(key);
            Console.WriteLine("Output of KeyName Value="+result);

            // Check if Exists
            bool found = cache.TryGetValue(key, out result);

            Console.WriteLine("KeyName Found=" + result);

            // Delete item
            cache.Remove(key);


            //set item with token expiration and callback
            TimeSpan expirationMinutes = System.TimeSpan.FromSeconds(0.1);
            var expirationTime = DateTime.Now.Add(expirationMinutes);
            var expirationToken = new CancellationChangeToken(
                new CancellationTokenSource(TimeSpan.FromMinutes(0.001)).Token);

            // Create cache item which executes call back function
            var cacheEntryOptions = new MemoryCacheEntryOptions()
           // Pin to cache.
           .SetPriority(Microsoft.Extensions.Caching.Memory.CacheItemPriority.Normal)
           // Set the actual expiration time
           .SetAbsoluteExpiration(expirationTime)
           // Force eviction to run
           .AddExpirationToken(expirationToken)
           // Add eviction callback
           .RegisterPostEvictionCallback(callback: CacheItemRemoved);
            //add cache Item with options of callback
            result = cache.Set(key,"Call back cache Item", cacheEntryOptions);


            Console.WriteLine(result);



            Console.ReadKey();

        }

        private static void CacheItemRemoved(object key, object value, EvictionReason reason, object state)
        {
            Console.WriteLine(key + " " + value + " removed from cache due to:" + reason);
        }
    }
}

Output:

Output of KeyName Value=Update 1
KeyName Found=Update 1
Call back cache Item
KeyName Call back cache Item removed from cache due to:TokenExpired

If you will check the above code, you will find, in the .NET Core Memory cache example, we create cache using Set() and get it's value using Get(), methods.

We can also add Call back functions using MemoryCacheEntryOptions, by setting Expiration time of cache.

If you have any questions regarding above post, feel free to ask it in below comment's section.

You may also like to read:

output caching in MVC

Enable Caching in IIS