c# - 我应该在课堂上的哪个位置填充 MemoryCache?
问题描述
我有一个返回缓存的类,目前的用法是:
var cache = new ProductCache().Get();
thencache
是一个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();
解决方案
如果您想重用缓存逻辑但希望子类具有灵活性,您可以使用模板方法模式:
public abstract class BaseCache
{
private readonly object cacheLock = new object();
protected ObjectCache cache = MemoryCache.Default;
public List<string> Get()
{
// for example. It could be anywhere and return any type.
ChildLogic();
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();
}
}
protected abstract void ChildLogic();
protected abstract void PopulateFromElsewhere();
}
然后在您的子类中,您应该ChildLogic()
以PopulateFromElsewhere()
任何您想要的方式实现。
当然,你根本不需要有方法ChildLogic()
。
推荐阅读
- python - Python分割数据记录
- java - 如果 Java 中的类具有私有 mutator 方法,它可以是不可变的吗?
- asp.net-web-api - 检查不记名令牌
- javascript - 如何使用鼠标旋转 3D 对象而不使用three.js 将其旋转到屏幕外?
- java - 使用 Selenium Webdriver 关闭警报
- angular - Selenium net.serenity.bdd.core.exceptions.SerenityManagedException 元素超时
- android - 三星 Tab E 上的 Chromecast 无法连接
- css - 通过增加字体填充剩余空间
- javascript - 每次在 JavaScript 中生成数组时递增或重置计数
- sql - 仅当列在 SQL 查询中同时包含字符和数字时,如何选择数字?