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
ToolUse for
ThreadRarely directly; dedicated long-running thread
Task.RunPush CPU-bound work to the thread pool
Parallel.For/ForEach/ForEachAsyncData 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.