作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
尽管这个问题是关于MemoryCache
类的,但我可以想象Dictionary
或ConcurrentDictionary.GetOrAdd
的需求相同,其中valueFactory
-lambda也是一个冗长的操作。
本质上,我想在每个项目的基础上同步/锁定线程。我知道MemoryCache
是线程安全的,但是仍然需要检查项目是否存在并在不存在时添加该项目,仍然需要进行同步。
考虑以下示例代码:
public class MyCache
{
private static readonly MemoryCache cache = new MemoryCache(Guid.NewGuid().ToString());
public object Get(string id)
{
var cacheItem = cache.GetCachedItem(id);
if (cacheItem != null) return cacheItem.Value;
var item = this.CreateItem(id);
cache.Add(id, item, new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(20)
});
return item;
}
private object CreateItem(string id)
{
// Lengthy operation, f.e. querying database or even external API
return whateverCreatedObject;
}
}
cache.GetCachedItem
和
cache.Add
。但是由于
CreateItem
是一个冗长的操作(因此
MemoryCache
),所以我不想像此代码那样锁定所有线程:
public object Get(string id)
{
lock (cache)
{
var item = cache.GetCachedItem(id);
if (item != null) return item.Value;
cache.Add(id, this.CreateItem(id), new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(20)
});
}
}
CreateItem
调用
id
。
Semaphore
创建一个唯一的名为
id
的代码,因此锁定是在每个项目的基础上进行的。但这将是系统资源的杀手,因为我们不想在我们的系统上注册+ 100K命名信号量。
NamedReaderWriterLocker
类乍看起来很有希望,但使用起来很危险,因为当两个线程同时进入
ReaderWriterLockSlim
的
ConcurrentDictionary
时,两个线程可能会使用相同名称的另一个
valueFactory
实例。也许我可以将此实现与
GetLock
方法内的一些附加锁一起使用。
最佳答案
由于您的 key 是字符串,因此您可以锁定string.Intern(id)
。
MSDN文档:System.String.Intern
IE。
lock (string.Intern(id))
{
var item = cache.GetCachedItem(id);
if (item != null)
{
return item.Value;
}
cache.Add(id, this.CreateItem(id), new CacheItemPolicy
{
SlidingExpiration = TimeSpan.FromMinutes(20)
});
return /* some value, this line was absent in the original code. */;
}
关于c# - 在每个项目的基础上同步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36839135/
我一直在从事一个开源项目。它使用安装在 jdk8 镜像上的构建生成的 debian (.deb) 软件包创建 docker 镜像。 但最近我开始犯错误,不幸的是我无法克服它。一旦通过 Dockerfi
我正在尝试使这些卡片可点击以重定向到另一个屏幕,但我无法弄清楚 let cards = this.state.items.map(item => ( Actions.dog
我是一名优秀的程序员,十分优秀!