【发布时间】:2016-02-22 13:39:24
【问题描述】:
我在我的 c# web-api 服务器中使用了一些缓存控制。
我使用以下代码:
private static MemoryCache _cache = new MemoryCache("ExampleCache");
public static object GetItems(string key) {
return AddOrGetExisting(key, () => InitItem(key));
}
private static List<T> AddOrGetExisting<T>(string key, Func<List<T>> valueFactory)
{
var newValue = new Lazy<List<T>>(valueFactory);
var oldValue = _cache.AddOrGetExisting(key, newValue, new CacheItemPolicy()) as Lazy<List<T>>;
try
{
return (oldValue ?? newValue).Value;
}
catch
{
_cache.Remove(key);
throw;
}
}
private static List<string> InitItem(string key) {
// im actually fetching a list from the db..but for the sake of the example
return new List<string>()
}
现在,一切正常。但是,这一次我想更新我的数据库中的一些东西,然后我想更新缓存控件,这样我就不必查询我的数据库了。
假设我使用一个看起来像这样的对象
Public class Foo{
public string Id;
public List<string> values;
}
在这个例子中假设T 是Foo
我需要将一个项目添加到存储在_cache by Foo 的Id 字段中的列表中。如果该过程是线程安全的,我会非常高兴。
TIA。
【问题讨论】:
-
因此您可以通过在内存缓存中传递密钥来获取列表并将项目添加到该列表中......有什么问题?你没有访问 memoryCache 实例的权限吗?
-
没有线程安全的方法可以将项目添加到 _cache 返回的列表中。你会考虑更细粒度的缓存吗?每个
Foo是否都负责根据需要查找和代理缓存或数据库? (至少是解决问题的一种可能方法)或者,您可以使用ConcurrentBag而不是列表(我建议您将返回类型更改为IList<T> -
@Viru 我得到了 Foo 的确切实例吗? Foo 上的更改会影响内存缓存中的对象吗?因为我认为可以创建一个新指针并且更改不会影响原始对象。 willaien,我没有得到你的最后两句话,但我认为没有其他线程安全可做,我可以简单地在每个插入上使用 lock 并且它是安全的,问题在于在此过程中创建的瓶颈..
-
@willaien 如果我从 GetItems 方法接收的对象是内存中的原始对象,那么我可以实现线程安全列表。但是,它是这样工作的吗?正如我对 Viru 所说的那样,我不确定它的工作方式
-
@OriRefael List 是引用类型,因此您所做的更改将影响到原始对象,
标签: c# memorycache