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.