mtkachenko mtkachenko - 10 months ago 52
ASP.NET (C#) Question

ASP.NET: cache task and call its result in synchronous code

I have synchronous HttpHandler. I want to cache result of HttpClient.GetAsync and use it in my HttpHandler. I did it this way:

public static class CacheFacade
private static Cache Cache => HttpRuntime.Cache;
private const string CacheKey = "asynccache";

public static string GetStringFromCache()
if (Cache[CacheKey] == null)
//fallback here; I can use data from some synchronous source
return "init cache" + " - " + Thread.CurrentThread.ManagedThreadId;
var task = (Task<string>) Cache[CacheKey];

if (!task.IsCompleted)
//and fallback here too
return task.Status + " - " + DateTime.UtcNow + " - " + Thread.CurrentThread.ManagedThreadId;

return task.Result;

private static void InitCache()
var task = Task.Run(GetDataAsync);
Cache.Insert(CacheKey, task, null, DateTime.Now.Add(TimeSpan.FromSeconds(10)),

private static async Task<string> GetDataAsync()
using (var httpClient = new HttpClient())
await Task.Delay(TimeSpan.FromSeconds(2));
var res = await httpClient.GetAsync("");
return res.StatusCode + " - " + DateTime.UtcNow + " - " + Thread.CurrentThread.ManagedThreadId;

It works. Does this approach have any disadvantages?

usr usr
Answer Source

This is OK.

Note, that these cache items can only be stored in-process. You can't use an out-of-process cache because tasks cannot be serialized. You might or might not care about that.

In your fallback here; I can use data from some synchronous source handling you can also block on the task (or await it if architecturally possible).

HTTP handlers support async processing using tasks as well. I believe you need a tiny helper/wrapper for that which is easy to write or available on the web.