gpt4 book ai didi

c# - 当 valueFactory 有副作用时,ConcurrentDictionary.GetOrAdd

转载 作者:太空狗 更新时间:2023-10-30 01:59:09 26 4
gpt4 key购买 nike

我试图通过为一些非常核心的功能引入缓存层来减轻我的数据库服务器的工作,这些功能将值插入数据库中的表并检索 ID。这是在多线程环境中。

我的第一个方法是:

public class Cache {
private Dictionary<string, Int64> i;

public void Init() { /* init i with values from DB */ }

public Int64 Get(string value)
lock(i) {
Int64 id;
if (cache.i.TryGetValue(value, out id))
return id;

id = /* Insert to DB and retrieve ID */
cache.i[value] = id;
return id;
}
}

这很有帮助。然而,线程仍然相互等待很多。我想减少这个等待时间。我的第一个想法是使用 ConcurrentDictionary.GetOrAdd(key, valueFactory)。这是行不通的,因为可以多次调用 valueFactory。

我已经结束了这种方法:

public class Cache
{
private ConcurrentDictionary<string, Int64> i;

public void Init() { /* init i with values from DB */ }

public Int64 Get(string value)
{
Int64 id;
if (i.TryGetValue(value, out id))
return id;

lock (i)
{
if (i.TryGetValue(value, out id))
return id;

id = /* Insert to DB and retrieve ID */
i.TryAdd(value, id);
return id;
}
}

有更好的方法吗?这甚至是线程安全的吗?

最佳答案

您要做的是懒惰地创建一个只需要创建一次的对象,然后在创建后由任意数量的线程访问。 Lazy 正是为此而设计的:

public class Cache
{
private ConcurrentDictionary<string, Lazy<long>> i;

public void Init() { /* init i with values from DB */ }

public Int64 Get(string value)
{
return i.GetOrAdd(value, new Lazy<long>(() =>
CreateDatabaseRecordAndGetId()))
.Value;
}

private long CreateDatabaseRecordAndGetId()
{
throw new NotImplementedException();
}
}

关于c# - 当 valueFactory 有副作用时,ConcurrentDictionary.GetOrAdd,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24919649/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com