Joydip Kanjilal
Contributor

How to cache Task objects for improving performance

opinion
Apr 20, 20173 mins
Software Development

Cache your Task objects to improve performance by preventing the unnecessary expensive operations from being executed

task caching
Credit: IDG

Caching is a state management strategy that long has been used in applications to store relatively stable and frequently accessed data for faster access. It helps you to boost your application’s performance primarily because you can save on the consumption of resources in your system to access the data from the cache. Caching can also make sure that your application gets the data it needs even when the data store is not available.

So far so good. Now, we have used data caching many times in our applications for improving the application’s performance. But we can cache Task objects as well!

Task caching

Task caching is an approach towards caching in which instead of caching the results of the execution of a Task, you cache the Tasks instances themselves. In doing so, you can reduce the overhead of expensive operations each time a new Task instance is started.

Now, what if the Task fails? Note that we should not cache failed or faulted Tasks, i.e., negative caching should not be considered. Let’s now dig into some code and understand how this can be implemented.

Implementing Task caching

The following method attempts to get or add data from the cache based on the key passed as a parameter.

public static async Task<object> GetOrAddDataInCache(string key)

        {

            if (key == null)

                return Task.FromResult<object>(null);

            object result;

            if (!cache.TryGetValue(key, out result))

            {

                result = await SomeMethodAsync();

                cache.TryAdd(key, result);

            }

            return result;

        }

The cache collection being used here is:

static ConcurrentDictionary<string, object> cache = new ConcurrentDictionary<string, object>();

Now, in this example, we have cached the data, not the Task instance. The following method illustrates how Task caching can be achieved.

public static async Task<object> GetOrAddTaskInCache(string key)

        {

            if (key == null)

                return Task.FromResult<object>(null);

            Task<object> result;

            if (!cache.TryGetValue(key, out result))

            {

                result = await Task.FromResult(SomeMethodAsync());

                cache.TryAdd(key, result);

            }

            return result;

        }

Note how the Task object is added to the cache if it’s not available. If the Task instance is available in the cache, it is returned else, a call is made to the asynchronous method and the resultant Task instance is inserted in the cache.

And, here’s the cache object for your reference.

static ConcurrentDictionary<string, Task<object>> cache = new ConcurrentDictionary<string, Task<object>>();

Note that we are using a ConcurrentDictionary to store the cached data. You can also take advantage of other cache stores if you want to. The asynchronous method SomeMethodAsync can perform some long running operation. I leave it to my readers to change it as per the needs. Here’s a simple version of the method anyway for your reference.

public static async Task<object> SomeMethodAsync()

        {

            //Write your code here for some long running operation

            await Task.Delay(100); //Simulates a delay of 100 milliseconds

            return "Hello World!";

        }

OK, but should I be caching the Task objects always? Absolutely not! Usually, the overhead of state machine allocation when creating a Task instance is negligible, but you can still take advantage of Task caching when you would need to perform relatively expensive operations in your applications often.

This was just a simple implementation to illustrate how Task caching works. We didn’t consider many things here. You can refer to this nice post to read a more elaborate implementation on Task caching.

Joydip Kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author