Skip to content

ConcurrentDictionary.GetOrAdd is not always thread safe. #33221

@hikalkan

Description

@hikalkan

See the implementation:

TValue resultingValue;
if (!TryGetValueInternal(key, hashcode, out resultingValue))
{
TryAddInternal(key, hashcode, valueFactory(key), false, true, out resultingValue);
}

Two problems here:

  1. Multiple threads may check TryGetValueInternal then gets false and calls TryAddInternal which causes the factory method execuites multiple times. If the factory is doing a heavy work, this is a significiant problem.
  2. If the factory method is using another shared object, then factory method will be concurrently executed and the shared object will be concurrently accessed, which can be a bug source (we had this problem)

I think GetOrAdd should be completely thread safe since we trust in the ConcurrentDictionary, use it without checking its internal implementation.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions