gpt4 book ai didi

c# - ConcurrentDictionary.GetOrAdd() 是否保证每个键只调用一次 valueFactoryMethod?

转载 作者:IT王子 更新时间:2023-10-29 04:40:40 29 4
gpt4 key购买 nike

问题:我需要实现对象缓存。缓存需要是线程安全的并且需要按需填充值(延迟加载)。这些值是通过 Key 的 Web 服务检索的(操作缓慢)。所以我决定使用 ConcurrentDictionary 及其 GetOrAdd()具有值工厂方法的方法假设操作是原子的和同步的。不幸的是,我在 MSDN 文章中发现了以下声明:How to: Add and Remove Items from a ConcurrentDictionary :

Also, although all methods of ConcurrentDictionary are thread-safe, not all methods are atomic, specifically GetOrAdd and AddOrUpdate. The user delegate that is passed to these methods is invoked outside of the dictionary's internal lock.

嗯,这很不幸,但仍然没有完全回答我的答案。

问题:每个键只调用一次值工厂吗?在我的具体情况下:是否有可能正在寻找相同键的多个线程针对相同的值对 Web 服务产生多个请求?

最佳答案

正如其他人已经指出的那样,valueFactory可以被多次调用。有一个缓解此问题的通用解决方案 - 让您的 valueFactory返回 Lazy<T>实例。尽管可能会创建多个惰性实例,但实际的 T仅当您访问 Lazy<T>.Value 时才会创建值属性(property)。

具体来说:

// Lazy instance may be created multiple times, but only one will actually be used.
// GetObjectFromRemoteServer will not be called here.
var lazyObject = dict.GetOrAdd("key", key => new Lazy<MyObject>(() => GetObjectFromRemoteServer()));

// Only here GetObjectFromRemoteServer() will be called.
// The next calls will not go to the server
var myObject = lazyObject.Value;

此方法在 Reed Copsey's blog post 中有进一步解释。

关于c# - ConcurrentDictionary.GetOrAdd() 是否保证每个键只调用一次 valueFactoryMethod?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31637394/

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