TryAdd conditionally inserts a key-value pair into a ConcurrentDictionary. It treats an existing key as normal contention: insertion succeeds normally, or returns false instead of throwing an exception. section 13.2.1
Replacing Add with TryAdd removes the exception caused by a competing insertion, but a TryGetValue-then-TryAdd sequence can still create separate copies of the same item on multiple threads. section 13.2.1
Use the result and choose the operation according to the concurrency requirement:
- Check the Boolean result when the caller must know whether insertion won the race. section 13.2.1
- Prefer GetOrAdd when lookup and initialization must be combined into one operation that avoids duplicate item copies. section 13.2.1
- Do not confuse this overload with BlockingCollection<T>.TryAdd, which waits for capacity up to a timeout and returns false when the timeout expires. section 13.2.2
Thread-safe cache insertion
if (!dictionary.TryGetValue(itemId, out var item)) { item = CreateAndInitializeItem(itemId); dictionary.TryAdd(itemId, item); } This prevents an insertion exception, although concurrent callers can still initialize separate item instances. section 13.2.1
Listing 13.8 Thread-safe cache with ConcurrentDictionary.GetOrAdd
var item = dictionary.GetOrAdd(itemId,CreateAndInitializeItem);
Compare the TryAdd cache pattern with GetOrAdd’s single-line combined operation. section 13.2.1
