[英]IMemoryCache in .NET Core GetOrCreate function is called multiple times
I'm using IMemoryCache to speed up my web application.我正在使用 IMemoryCache 来加速我的 Web 应用程序。 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.缓存功能最多需要 20 秒。
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.我们网上商店中的一个页面请求多次使用这些Articles
,并且我们的商店中总是有多个用户。 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.现在我们遇到了缓存方法最多需要 20 秒的问题,在这 20 秒内, Articles
会被多次调用,并且每次CacheArticles()
方法都会再次被调用,因为缓存还没有被填满。
How can we avoid this?我们怎样才能避免这种情况?
You can use lock
to ensure that CacheArticles
is called only once at a time.您可以使用lock
来确保一次只调用一次CacheArticles
。
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请注意,它会在CacheArticles
运行时阻塞所有调用线程,这对您来说可能是也可能不是问题
This is where lock
statement comes in.这就是lock
语句的用武之地。
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.请注意__AriticleTableLock
是static
因为它将为应用程序中的所有用户共享。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.