gpt4 book ai didi

c# - 在 C# 中使用数据库值填充 ConcurrentDictionary 的锁定注意事项

转载 作者:行者123 更新时间:2023-11-30 14:15:34 25 4
gpt4 key购买 nike

当我在这里填写我的 ConcurrentDictionary 时是否需要使用 lock(lockObj){} block ?对于一些背景知识,这将在 MVC 应用程序中使用,但我怀疑场景问题与任何多线程应用程序相关。

在搜索 stackoverflow 时,我没有找到这个确切的场景。在第一次从 GetOptionById 值请求值时调用,它可以由两个单独的线程调用。

1) 将 List 对象的值设置为私有(private)静态值是否更好,您将其锁定以希望在填充 ConcurrentDictionary 之前不会多次调用数据库?

2) 那(上面的#1)是否必要,或者 ConcurrentDictionary 是否足够聪明,可以自己解决这个问题?在此先感谢您的任何意见。

public class MyOptions
{
static string GetOptionById(int id)
{
if (options == null || options.Count <= 0)
FillOptionList();
return options[id];
}

static void FillOptionList()
{
List<MyBusinessObject> objects = DataAccessLayer.GetList();
foreach (MyBusinessObject obj in objects)
options.TryAdd(obj.Id, obj.Name);
}

private static ConcurrentDictionary<int, string> options = new ConcurrentDictionary<int, string>();
}

编辑:感谢大家的意见,这是一种更安全的方法吗?

    public static string OptionById(int id)
{
if (!options.ContainsKey(id))
{
//perhaps this is a new option and we need to reload the list
FillOptionsOrReturn(true /*force the fill*/);
return (!options.ContainsKey(id)) ? "Option not found" : options[id];
}
else
return options[id];
}

private static void FillOptionsOrReturn(bool forceFill = false)
{
List<MyBusinessClass> objectsFromDb = null;
lock (lockObj)
{
if (forceFill || options == null || options.Keys.Count <= 0)
reasons = DataAccessLayer.GetList();
}
if (objectsFromDb != null)
{
foreach (MyBusinessClass myObj in objectsFromDb)
options.TryAdd(myObj.id, myObj.name);
}
}

private static ConcurrentDictionary<int, string> options = new ConcurrentDictionary<int, string>();
private static object lockObj = new object();

最佳答案

你得到的肯定是不安全的。考虑:

线程 X 和 Y 都调用 GetOptionById大致在同一时间。 X 发现它需要填充字典,并开始这样做。第一个结果返回,并添加到字典中。

然后 Y 发现有一个条目,并假设字典是完整的 - 所以它获取它感兴趣的选项,这可能不是已经加载的选项。 p>

这看起来很适合使用 Lazy<T> ...你可以在那里选择合适的选项,这样一次只能有一个线程填充字典——第二个线程会等到第一个线程完成后再继续。这样“填充字典”就有效地变成了原子。

如果您在第一次加载后永远不需要更新字典,您甚至可能只需要 Lazy<Dictionary<string, string>> 就可以了。 - 拥有多个读者是安全的,只要没有作者。我相信 Lazy<T>将适本地处理内存障碍。

关于c# - 在 C# 中使用数据库值填充 ConcurrentDictionary 的锁定注意事项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9843970/

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