简体   繁体   中英

IMemoryCache in .NET Core GetOrCreate function is called multiple times

I'm using IMemoryCache to speed up my web application. Therefor I cache a whole database table of products with all the linked details in a webshop. The caching function takes up to 20 seconds.

private List<Article> Articles {
    get {
        return _cache.GetOrCreate("Articles ", entry =>
        {
            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24);
            return CacheArticles(); // takes 20 seconds
        });
    }
}

One page-request in our webshop uses the Articles multiple times and there are always multiple users on our shop. Now we have the problem that the caching method takes up to 20 seconds, within that 20 seconds the Articles are called a lot of times and every time the CacheArticles() method is called again, because the cache was not filled yet.

How can we avoid this?

You can use lock to ensure that CacheArticles is called only once at a time.

private readonly object locker = new object();

private List<Article> Articles {
    get {
        lock (locker)
        {
            return _cache.GetOrCreate("Articles ", entry =>
            {
                entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(24);
                return CacheArticles(); // takes 20 seconds
            });
        }
    }
}

Note that it will block all calling threads while CacheArticles runs, this may or may not be a problem for you

This is where lock statement comes in.

Define this at you class level as static to being shared for everyone that access that class.

private static object __AriticleTableLock = new object();

Then where you want to fill your cache use this code:

 lock (__AriticleTableLock)
 {
   // your code comes here...
 }

This cause this part of code is accessible for only one user.

Note that __AriticleTableLock is static because it's gonna be shared for all users in your application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM