我有一个返回缓存的类,当前使用情况:
var cache = new ProductCache().Get();
然后cache
是可以枚举的List<>
。
当在构造函数中实例化ProductCache()
或检索它时,我真的应该填充此缓存吗?
选项1:
public class ProductCache
{
private readonly string key = "Product";
private readonly object cacheLock = new object();
ObjectCache cache = MemoryCache.Default;
public ProductCache()
{
}
public List<string> Get()
{
// Try to return.
var data = cache.Get(key) as List<string>;
if (data != null)
return data;
lock (cacheLock)
{
// Check again.
data = cache.Get(key) as List<string>;
if (data != null)
return data;
// Populate, and return.
data = PopulateFromElsewhere();
cache.Set(key, data, DateTimeOffset.UtcNow.AddSeconds(20));
return data;
}
}
private List<string> PopulateFromElsewhere()
{
return new List<string> { "Ball", "Stick" };
}
}
选项2:
public class ProductCache
{
private readonly string key = "Product";
private readonly object cacheLock = new object();
ObjectCache cache = MemoryCache.Default;
public ProductCache()
{
var data = cache.Get(key);
if (data != null)
return;
lock (cacheLock)
{
// Check again.
data = cache.Get(key);
if (data != null)
return;
// Populate, and return.
PopulateFromElsewhere();
}
}
public List<string> Get()
{
return cache.Get(key) as List<string>;
}
private void PopulateFromElsewhere()
{
var data = new List<string> { "Ball", "Stick" };
cache.Set(key, data, DateTimeOffset.UtcNow.AddSeconds(20));
}
}
第二个选项线程是否安全(足够)?我认为第一个是....
也有其他缓存。它们都很相似,所以我打算将所有实际的锁定/加载行为放在抽象类中
var storeCache = new StoreCache().Get();
var otherCache = new OtherCache().Get();
我猜另一个选择是一个静态类,但是由于我无法做出抽象的描述,因此需要重复使用锁定机制……这可能非常好,并且使用起来就像……
>var cache = GlobalCache.Stores();
答案 0 :(得分:0)
如果您想重用缓存逻辑,但是想要子类的灵活性,则可以使用Template方法模式:
ChildLogic()
然后在子类中,您应该以任何需要的方式实现PopulateFromElsewhere()
和ChildLogic()
。
当然,您根本不需要使用方法{{1}}。