【发布时间】:2019-03-14 04:22:43
【问题描述】:
我正在使用下面的代码来缓存项目。这是非常基本的。
我遇到的问题是,每次它缓存一个项目时,部分代码都会锁定。因此,每小时大约有一百万件物品到达,这是一个问题。
我尝试为每个 cacheKey 创建一个静态锁对象字典,以便锁定是细粒度的,但这本身就成为管理它们过期等问题...
有没有更好的方法来实现最小锁定?
private static readonly object cacheLock = new object();
public static T GetFromCache<T>(string cacheKey, Func<T> GetData) where T : class {
// Returns null if the string does not exist, prevents a race condition
// where the cache invalidates between the contains check and the retrieval.
T cachedData = MemoryCache.Default.Get(cacheKey) as T;
if (cachedData != null) {
return cachedData;
}
lock (cacheLock) {
// Check to see if anyone wrote to the cache while we where
// waiting our turn to write the new value.
cachedData = MemoryCache.Default.Get(cacheKey) as T;
if (cachedData != null) {
return cachedData;
}
// The value still did not exist so we now write it in to the cache.
cachedData = GetData();
MemoryCache.Default.Set(cacheKey, cachedData, new CacheItemPolicy(...));
return cachedData;
}
}
【问题讨论】:
-
您说您每小时有一百万个缓存请求,但是您多久创建一次新缓存?如果您只有 5 个缓存并且平均每 30 分钟清除一次,那么您的锁定基本上不会占您的开销。另一方面,如果您每 30 秒填充 10 个缓存,您的锁定策略将增加大量开销。您从不同的缓存中请求未填充的项目的频率也很重要。如果很多,你不应该这样做,如果不是,这不太可能是瓶颈。
-
@Servy Million
new项目在一小时内到达。因此将建立一个锁,获取项目并添加到缓存中。