C# race conditions explained: lost updates, check-then-act, Interlocked and concurrent collections
Common forms: lost update (++), check-then-act, and a Dictionary modified from multiple threads (which can get corrupted internally).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | // ====================================================================== // Q: What is a race condition? Show an example. // // Common forms: lost update (++), check-then-act, and a Dictionary modified from // multiple threads (which can get corrupted internally). Fixes: immutable data, // Interlocked, lock, concurrent collections, or no shared state at all (scoped // services). In the database the same problem is solved with an atomic UPDATE or // a concurrency token (Q60-Q61). // ====================================================================== public class Stats // singleton: shared by all requests { private int _orders; public void OnOrder() => _orders++; // ✗ read-modify-write: with 2 threads one increment is lost } // ✓ Interlocked.Increment(ref _orders); // ✗ check-then-act: two threads both see "not there" and both load it if (!_cache.ContainsKey(sku)) _cache[sku] = await LoadAsync(sku); |