Is ConcurrentDictionary.GetOrAdd() guaranteed to invoke valueFactoryMethod only once per key?

前端 未结 3 1718
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-07 16:29

Problem: I need to implement object cache. The cache need to be thread-safe and need to populate values on demand(lazy loading). The values are retrieved vi

3条回答
  •  不思量自难忘°
    2021-01-07 16:48

    As others have already pointed out, valueFactory may be invoked more than once. There is a common solution that mitigates this issue - have your valueFactory return a Lazy instance. Although it's possible that multiple lazy instances will be created, the actual T value will only be created when you access Lazy.Value property.

    Specifically:

    // 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(() => GetObjectFromRemoteServer()));
    
    // Only here GetObjectFromRemoteServer() will be called.
    // The next calls will not go to the server
    var myObject = lazyObject.Value;
    

    This method is further explained in Reed Copsey's blog post

提交回复
热议问题