我使用以下方法来执行一些简单的缓存。问题是,我需要缓存一个会话令牌以进行某些 API 访问,这在 24 小时内有效。
问题是,如果我的 api 调用因令牌过期而反弹,我想使用以下刷新方法。但是,我想会出现并发问题,如果客户端请求正在删除/刷新令牌,而下一个客户端已经检查了令牌的存在,并且还将开始刷新删除令牌,则他们可能会遇到问题。如何在刷新时有效地锁定对此令牌的访问?
public class CacheUtils : ICacheService
{
public T Get<T>(string cacheKey, int hoursUntilExpire, Func<T> getItemCallback) where T : class
{
var item = HttpRuntime.Cache.Get(cacheKey) as T;
if (item != null) return item;
item = getItemCallback();
HttpRuntime.Cache.Insert(cacheKey, item, null, DateTime.UtcNow.AddHours(hoursUntilExpire), Cache.NoSlidingExpiration);
return item;
}
public void Refresh(string key)
{
HttpRuntime.Cache.Remove(key);
//Somehow refresh here with lock
}
}
正如你所说,你可以引入一个锁:
public class CacheUtils : ICacheService
{
private readonly object _lock = new object();
public T Get<T>(string cacheKey, int hoursUntilExpire, Func<T> getItemCallback) where T : class
{
T item;
lock (_lock)
{
item = HttpRuntime.Cache.Get(cacheKey) as T;
}
if (item != null) return item;
item = getItemCallback();
lock (_lock)
{
HttpRuntime.Cache.Insert(cacheKey, item, null, DateTime.UtcNow.AddHours(hoursUntilExpire), Cache.NoSlidingExpiration);
}
return item;
}
public void Refresh(string key)
{
lock (_lock)
{
HttpRuntime.Cache.Remove(key);
}
}
}