【发布时间】:2012-08-28 15:58:00
【问题描述】:
我有以下代码来缓存我在多线程应用程序中使用的并发字典中某些类的实例。
简单地说,当我使用 id 参数实例化类时,它首先检查字典中是否存在具有给定 id 的 privateclass 实例,如果不存在则创建 privateclass 的实例(这需要很长时间,有时需要几个秒),并将其添加到字典中以供将来使用。
public class SomeClass
{
private static readonly ConcurrentDictionary<int, PrivateClass> SomeClasses =
new ConcurrentDictionary<int, PrivateClass>();
private readonly PrivateClass _privateClass;
public SomeClass(int cachedInstanceId)
{
if (!SomeClasses.TryGetValue(cachedInstanceId, out _privateClass))
{
_privateClass = new PrivateClass(); // This takes long time
SomeClasses.TryAdd(cachedInstanceId, _privateClass);
}
}
public int SomeCalculationResult()
{
return _privateClass.CalculateSomething();
}
private class PrivateClass
{
internal PrivateClass()
{
// this takes long time
}
internal int CalculateSomething()
{
// Calculates and returns something
}
}
}
我的问题是,我是否需要在外部类构造函数的生成和赋值部分周围添加一个锁,以使这段代码线程安全,还是它本来就很好?
更新:
在 SLaks 的suggestion 之后,尝试使用 ConcurrentDictionary 的GetOrAdd() 方法与Lazy 的组合,但不幸的是PrivateClass 的构造函数仍然调用了不止一次。测试代码见https://gist.github.com/3500955。
更新 2: 您可以在此处查看最终解决方案: https://gist.github.com/3501446
【问题讨论】:
标签: c# multithreading concurrency