liveBook · Manning

ImmutableInterlocked

As explained in C# Concurrency: Asynchronous and multithreaded programming

ImmutableInterlocked is a .NET API that provides atomic operations for updating references to immutable collections and related immutable values.

ImmutableInterlocked synchronizes updates to variables that reference immutable collections. It avoids protecting the entire operation with a lock while preserving immutable snapshots for readers. section 13.3.2 section 13.3.3

Use the API with an all-or-nothing discipline:

  • Use AddOrUpdate, GetOrAdd, TryAdd, TryRemove, and TryUpdate with ImmutableDictionary<TKey,TValue>. section 13.3.3
  • Use Push and TryPop with ImmutableStack<T>, or Enqueue and TryDequeue with ImmutableQueue<T>. section 13.3.3
  • Retry after TryUpdate returns false: reread the value, validate the new state, and attempt the replacement again. section 13.3.3
  • Do not mix ImmutableInterlocked with ordinary immutable-collection methods or builders for concurrent modifications, and do not update multiple collections as one transaction. section 13.3.4 section 13.3.3

Selling the last available copy safely

A stock-management method reads the current quantity, rejects missing or empty inventory, and calls ImmutableInterlocked.TryUpdate to replace the referenced dictionary only if the observed quantity is still current. A failed update loops until another thread wins or inventory reaches zero. section 13.3.3

Listing 13.18 Thread-safe stock management with ImmutableInterlocked
   private ImmutalbeDictionery<string,int> _bookIdToQuantity = new();
   public bool TryToBuyBook(string bookId)
   {
      while(true)
      {
         if(!_bookIdToQuantity.TryGetValue(bookId, 
               out var copiesInStock))                        #1
            Return false;
         if(copiesInStock == 0)
            return false;
         if(ImmutableInterlocked.TryUpdate(                   #2
               ref _bookIdToQuantity, bookId,                 #2
               copiesInStock-1, copiesInStock))               #2
            return true;                                      #3
      }                                                       #4
   }
}

Runnable C# listing showing the TryUpdate retry loop for thread-safe inventory management. section 13.3.3

How C# Concurrency: Asynchronous and multithreaded programming covers it

How deep it goes
Explains compare-and-replace updates, retry loops, and synchronization boundaries, but defers implementation details beyond the API patterns.
Examples
Demonstrates concurrent book-stock decrements through an ImmutableDictionary and a TryUpdate retry loop.
What it assumes
Assumes familiarity with immutable collections, shared variables, concurrent access, and compare-and-update operations.
What you can do after
Apply it via ImmutableInterlocked methods to coordinate single-collection updates without locking the entire access method.
How it connects
Connects immutable collections with ConcurrentDictionary, ImmutableDictionary, immutable queues, immutable stacks, locks, and builders.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of C# Concurrency: Asynchronous and multithreaded programming. The section links point to the parts of the book it draws on.