Immutable data and no shared state: the best option.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // ====================================================================== // Q: How do you make code thread-safe? // // - Immutable data and no shared state: the best option. // - lock: for short critical sections. It does not allow await inside it (.NET // 9+ has the System.Threading.Lock type). // - SemaphoreSlim: for async critical sections or limiting concurrent // operations. // - Interlocked: for atomic counters. ConcurrentDictionary, Channel<T> for // producer/consumer. // - Watch out: a singleton service is shared across all requests, so it must be // thread-safe. // ====================================================================== private readonly SemaphoreSlim _gate = new(1, 1); public async Task RefreshTokenAsync(CancellationToken ct) { await _gate.WaitAsync(ct); // only one refresh at a time try { _token = await FetchTokenAsync(ct); } finally { _gate.Release(); } } |