
Highlight essential resources for this course, including asynchronous programming with .NET and C# 7, and Stephen Cleary’s concurrency cookbook, blog, and Stephen Taub’s parallel programming guidance.
Explore the basic concepts of multithreading and parallel programming in C#, including threads, processes, scheduling, concurrency, and common pitfalls of long running operations.
Explore the differences between synchrony, concurrency, and parallel computing, and learn how threads and processes enable asynchronous, interleaved execution on multi-core architectures.
Explore how processes isolate programs and how threads share resources within a process. Understand thread pools, thread scheduling, preemptive multitasking, priorities, stacks, and thread-local storage.
Understand why async programming matters for reliable, responsive apps by avoiding hangs and leveraging parallel techniques to handle data efficiently in modern environments.
In the multithreading and parallel programming in c# course, this demo shows long-running operations block the UI thread and fix by using a separate thread with a task and dispatcher.
Explore the challenges of multithreading, including designing parallel algorithms and synchronizing tasks, while learning why asynchronous code is harder to debug and how async/await helps.
Explore how synchronization handles events independent of the main program flow, and how concurrency lets multiple tasks run and interleave without blocking the UI, guided by the thread scheduler.
Kick off this section by exploring processes from starting a process to querying the operating system, plus thread pools, IO-bound operations, and legacy APM and EAP patterns.
Explore starting a thread using the old API before TPL, create a thread, pass parameters via the thread start delegate, and observe thread IDs and OS mapping.
Investigate stopping threads safely via cooperative cancellation and cancellation tokens, compare abort and interrupt risks, and learn to handle thread exceptions within the thread to stop tasks properly.
Coordinate threads using the join method to wait for completion with or without timeout, and distinguish foreground versus background threads; prefer thread pools over manual threads.
Understand legacy COM usage, the apartment threading model (STA and MTA), and marshaling for UI components within Windows Forms and WPF, including setting a thread's apartment state.
Discover how thread pools reuse threads to process work items, balance threads with the queue workload, and cap maximum threads to improve efficiency in multithreading.
Explore how the thread pool uses worker and I/O threads to optimize CPU and I/O resource use, balancing work items and avoiding idle threads through dynamic thread creation.
Demonstrate how I/O-bound operations execute asynchronously without blocking the UI thread, via IO completion ports and the OS's async model.
Explore the asynchronous programming model (APM) and the event-based asynchronous pattern (EAP), comparing begin/end I/O operations with callbacks and event-driven UI updates.
Learn to create and coordinate threads, pass arguments, manage priorities and task manager options, choose foreground or background threads, use a thread pool, and move from APM/EAP to the TPL.
Explore the task as a unit of work in multithreading, covering how to create tasks, their states, cancellation, waiting, I/O-bound tasks, exception handling, nested tasks, and TaskCompletionSource.
Understand that a task is an ongoing unit of work, startable with Task.Run or Task.StartNew, that may run on OS threads or IO threads and return results via Task<TResult>.
Explore the task life cycle in c#, from creation through waiting and running to final states, including ran to completion, cancelled, faulted, and status checks.
Learn cooperative cancellation in C# by using cancellation tokens and token sources to safely cancel long-running tasks. Use linked tokens and callbacks to coordinate cancellation while preserving state.
Chain tasks with the continue with method to run follow-up work after a task completes without blocking the main thread, using unconditional and conditional continuations.
Learn how waiting for a task blocks the main thread, use Task.Wait and Task.WaitAll to wait for multiple tasks, or Task.WaitAny and Task.WhenAny to react to the first completion.
Learn to create I/O bound tasks in C# using async patterns and task-based APIs, convert legacy APM and EAP to tasks, and optimize the thread pool.
Discover robust error handling in tasks by catching aggregate exceptions, flattening nested exceptions, and using handle predicates to respond to specific errors, while exploring wait versus fire-and-forget patterns.
Learn how global exception handling manages errors across threads and tasks, including unobserved task exceptions, the task scheduler, dispatcher, and app domain.
Learn how the task parallel library uses nested and child tasks, with child tasks propagating exceptions to the parent. DenyChildAttach prevents child task creation and isolates library tasks in APIs.
Learn how TaskCompletionSource creates a task from operations that start later, drive it with set result, set exception, or set canceled, and attach continuations for I/O-bound work.
Summarizes the task-based model in modern C#, covering task states, cancellation, continuations, waiting for completion, and async await, with handling of aggregate exceptions and child tasks.
Learn how async and await enable readable asynchronous code in C#, using task-based patterns, continuations, and proper handling of awaiting multiple tasks.
Explore the async return types void, task, and task of T, and learn when each is appropriate, including fire-and-forget risks and how exceptions propagate.
Discover where await fits in C# async code, including async delegates and lambdas; learn placement rules in catch, finally, and lock blocks, and coordinating multiple tasks with Task.WhenAll and select.
Understand how exceptions in async code propagate through tasks, including catching inside async methods, aggregate exceptions with Task.WhenAll, and the special case of async void where exceptions may go unobserved.
Master the async feature in C#, using the async keyword and Task types to write asynchronous code with try-catch exception handling, preparing for synchronization in multi-threaded apps.
Demonstrate how multiple threads share a single heap-allocated object, and show how non-atomic add and subtract operations cause race conditions in health updates.
Learn what atomic operations mean in multithreading and why increments are not atomic. Understand race conditions and how to achieve thread safety with atomic updates and synchronization, including interlocked.
Explore how the Interlocked class provides atomic increments, decrements, and exchanges to make multithreaded code safe, including compare-exchange for singletons, with practical examples in C#.
Learn to make thread-safe bank card operations using Monitor.Enter/Exit with try/finally, and extend locking via a disposable lock extension and timeout handling to prevent deadlocks.
Compare monitor limitations for read-heavy workloads and implement reader-writer lock slim to provide read locks for many threads and a single write lock for updates, boosting responsiveness.
Use a semaphore slim to limit concurrent access to a shared resource, capping at three. Model a nightclub where tasks wait for a slot, enter, and release it when done.
Explore how synchronization context enables cross-thread communication and ui updates via the ui thread's dispatcher, and compare post versus send for marshalling tasks across threads.
Explore deadlock in multithreading, where two threads hold locks and wait for each other, causing indefinite blocking. Learn to avoid deadlock by proper synchronization and timeouts.
Review how shared memory affects thread safety and object references on the heap. Explore atomic operations, interlocked primitives, monitors, synchronization context, reader-writer locks, semaphores, and signaling to prevent deadlocks.
Explore signal and wait handle constructs that coordinate inter-thread signaling, including AutoResetEvent, ManualResetEvent, CountdownEvent, Barrier, and Mutex.
Learn signaling patterns in C# using AutoResetEvent and ManualResetEventSlim, illustrated by a bank terminal example, with guidance on waiting, setting, and resetting the signal for correct asynchronous flow.
Learn how countdown event coordinates multiple threads by signaling, waiting for zero, and optionally adding counts, then use barrier to synchronize threads across multiple phases.
Implement process-level synchronization with a named system mutex to ensure a single instance of a wp application, shutting down if acquisition fails and releasing the mutex on exit.
Explore core signaling constructs in c# multithreading, including auto reset events, manual reset events, countdown events, barrier, and mutex, plus spinning for synchronizing work.
Explore the difference between blocking and spinning in multithreading with C#. Compare spinlock, spin wait, and spinning techniques for 10-nanosecond waits, and learn how to implement a synchronization primitive.
Compare blocking and spinning: blocking yields a time slice and a context switch, while spinning polls a condition in a loop; hybrid approaches improve efficiency, using spinlock for specialized synchronization.
Explore spin lock and spin wait in C#, using spin until with a memory barrier. Apply interlocked compare exchange for lock-free field updates; learn when spinning is efficient.
Explore building an updateable spin synchronization primitive for blocking calls with per-step timeouts and callbacks, using lock-based updates, event-driven messaging, and unit tests to verify wait behavior.
Learn how thread sleep or waiting blocks the calling thread and yields its processor time slice, then explore spinning with spinlocks for very short waits.
Explore two categories of concurrent collections, immutable collections and mutable concurrent collections, and learn to use immutable stacks, queues, lists, sets, and dictionaries, plus blocking collections for producer-consumer patterns.
Discover how immutable and concurrent collections enable thread-safe data access in multithreaded C# apps, using immutability to avoid locks and concurrent collections like stack, queue, and dictionary.
Implement an immutable stack that creates new instances for each operation, using a singleton empty stack and separate pop and peek, balancing immutability with memory efficiency.
Explore immutable stacks and queues for thread-safe, rarely updated data with the same time complexity as standard collections, including push, pop, enqueue, dequeue, and peek operations—note producer–consumer cautions.
Demonstrate using an immutable list in C# by adding, removing, and inserting elements. The binary-tree structure enables memory sharing and changes performance versus mutable lists, especially for index access.
Hash sets provide high performance with unique items, while immutable sorted sets guarantee a deterministic order after insertion, explaining why you might choose an immutable sorted set.
Explore immutable dictionary and immutable sorted dictionary usage, including instantiation, adding, updating with set item, indexing, and removal by key; compare unsorted and sorted dictionaries and key comparability.
Use builders to populate large immutable collections in C# efficiently by creating a mutable builder, adding items, then converting to immutable, with examples of immutable list and range-based population.
Explore concurrent queue and stack to achieve thread safety, using enqueue, dequeue, and peek with try dequeue and try peek for safe, accurate counts.
Explore concurrent bag, a thread safe collection for multi-threaded scenarios that does not guarantee item order. Learn its per thread storage, add and try take operations, and stealing impacts performance.
Learn how a concurrent dictionary enables safe, parallel stock management by add or update operations, try remove, and careful iteration in multi-threaded book sales simulations.
Explore the producer-consumer pattern using blocking collection over concurrent collections, implementing TryAdd and TryTake, a bounded capacity example with producers generating dirty cutlery and a consumer washing them.
Explore immutable and concurrent collections, including immutable stack, queue, list, sets, and dictionary, and learn how non-blocking algorithms enhance performance. Understand blocking collection and producer-consumer patterns and preview parallel programming.
Discover how to use the parallel class for foreach and invoke, apply linq to run queries in parallel, and cancel units of work running in parallel.
Partition a whole task into small chunks and execute those chunks in parallel using multi-threading, then collate the results in a thread-safe, high-performance way.
Explore the C# parallel class, using parallel invoke, parallel for, and parallel for each to run work in parallel, with batching and aggregate exceptions.
Explore cancelling parallel and PLINQ workloads in C# using cancellation tokens and sources, canceling long-running blocks with parallel foreach, with break and stop controls explained.
Master parallel programming in C# by using parallel foreach and invoke to run multiple delegates, and by applying AsParallel for parallel LINQ queries, with cancellation and loop control support.
Promote ongoing learning with the bonus lecture by inviting learners to join the mailing list, subscribe to the blog, and access exclusive discounts and links to additional media.
For the last two decades, computers became faster by increasing the number of CPU cores. However, the fact of having more cores itself doesn’t make a computer drastically faster if those cores are not used by software properly. We, as software developers, should know how to write asynchronous and parallel executing code to make our applications faster and more responsive.
This course is all about developing more responsive and fast programs. Multithreading and Parallel Computing are topics for those who already have some experience in programming, otherwise, you may face difficulties with understanding the content. Anyway, this course covers:
Theoretical foundations of asynchronous programming: main concepts, processes, threads and so on
Low-level Thread API, APM, and EAP
Task Parallel Library (TPL) including starting tasks, canceling tasks, chaining tasks, waiting for tasks, IO-based tasks, exceptions handling and other
Async and Await feature of C#
Synchronization including atomicity, Interlocked, Monitor (lock), ReaderWriterLockSlim, Semaphore, SynchronizationContext, and Mutex
Signaling constructs such as AutoResetEvent and ManualResetEventSlim, CountdownEvent and Barrier
Spinning including SpinWait, SpinLock and our own UpdateableSpin
ConcurrentCollections including ImmutableStack, ImmutableQueue, ImmutableList, Immutable Sets, ImmutableDictionary, ConcurrentStack, ConcurrentQueue, ConcurrentBag, BlockingCollection
Parallel Programming including Parallel class and PLINQ
Enroll and start learning the foundations of multithreading and parallel computing in .NET.