Roadmap › C# Language — Basics to Advanced › Module: Asynchronous and Parallel Programming
Lessons in this course (38)
35. Threads, Tasks, Parallel and thread safety
Intermediate★ Must knowLesson 35 of 38
| Tool | Use for |
|---|---|
Thread | Rarely directly; dedicated long-running thread |
Task.Run | Push CPU-bound work to the thread pool |
Parallel.For/ForEach/ForEachAsync | Data parallelism over collections |
PLINQ .AsParallel() | Parallel LINQ queries |
Channel<T> | Producer/consumer pipelines |
csharp
private readonly Lock _gate = new(); // C# 13 / .NET 9 (use 'object' on older versions)
private int _count;
public void Increment() { lock (_gate) { _count++; } }
Interlocked.Increment(ref _hits); // lock-free atomic counter
var cache = new ConcurrentDictionary<string, User>();
var user = cache.GetOrAdd(id, LoadUser);
using var sem = new SemaphoreSlim(3); // at most 3 concurrent operations
await sem.WaitAsync();
try { await CallApiAsync(); } finally { sem.Release(); }Race condition: two threads read-modify-write shared state without synchronisation. Deadlock: two threads each hold a lock the other needs — avoid by always taking locks in the same order and keeping lock scopes small. You cannot await inside a lock block — use SemaphoreSlim.