
Explore the core concepts of concurrency in C#, including parallel and asynchronous programming, and distinguish IO and CPU bound operations from sequential programming, multi threading, and multitasking.
Explore how concurrency enables doing several tasks at the same time to improve efficiency. See how parallelism uses multiple threads and asynchronous programming to serve more web requests concurrently.
explain parallel programming divides work and runs tasks simultaneously to save time. discover data and task parallelism, and how the task parallel library and plinq enable parallel processing of arrays.
Master asynchronous programming in C# to avoid blocking threads and keep user interfaces responsive, using async and await with Task to improve vertical scalability and IO-bound handling.
Explore the difference between I/O bound operations and CPU bound operations, and apply asynchronous programming for external I/O while using parallel programming for processor-bound tasks.
Explore sequential programming and the basics of concurrency. Clarify how multi threading, parallelism, and multitasking relate, including when threading does not imply parallelism and how an operating system schedules threads.
Explain determinism and non deterministic behavior, contrasting predictable inputs with the random class, and show how parallelism makes the order of console messages unpredictable if a specific order matters.
Install Visual Studio and configure the desktop development workload to prepare for concurrency work with the wind farms framework. Use the community edition if needed and consider cross-platform options.
Explore how concurrency uses parallel and asynchronous programming to run tasks simultaneously, improve vertical scalability and user interface responsiveness, and distinguish CPU-bound from I/O-bound work.
Explore concurrency in C#, focusing on asynchronous programming with async and await, progress reporting, task cancellation, and patterns for responsive, parallel apps.
Use async and await to implement asynchronous programming, freeing the current thread from waiting and preventing blocking, with applicability across various development environments and a simple application example.
Create a wind farms project in the net framework, drag a start button, add a loading gif, center the image, and demonstrate asynchronous programming.
Explore how asynchronous programming prevents the UI from freezing during long operations by awaiting delays and freeing the UI thread.
Learn how asynchronous methods return Task or Task<T> to represent future operations and why await enables non-blocking execution. See why void is avoided except in event handlers.
Explore how to implement asynchronous methods that return a value via Task<T> in C#, by calling a Web API, using async/await, and updating the UI.
Understand how errors occur in asynchronous tasks, how HTTP request exceptions are encapsulated in a task, and why awaiting with try-catch is essential to notify users.
Execute multiple tasks concurrently with Task.WhenAll to process many cards via an API. Use a thread-safe random generator to simulate approvals, measure performance with a stopwatch, and explore scalability issues.
Offload long-running work to a background thread with Task.Run to keep the UI responsive in a C# async program, using await and async methods to wait for results.
Limit concurrent tasks in C# by using SemaphoreSlim to throttle batched requests to a web API. The lecture demonstrates safe release on errors and practical batching for controlled parallelism.
Analyze credit card responses using Task.WhenAll to gather results, deserialize each response into a CardResponse with card and approve fields, identify rejected cards, and log outcomes to the console.
Learn how to report progress for multiple asynchronous tasks using IProgress, updating a progress bar and displaying percentages to users.
Learn how to report progress for multiple asynchronous tasks efficiently by using Task.WhenAny to update at intervals, reduce overhead, and calculate a running completion percentage.
Learn to cancel long-running tasks in C# by creating and passing a cancellation token from a token source to asynchronous operations, wiring a cancel button, and handling the cancellation exception.
Learn how to cancel a custom loop by passing a cancellation token, detect cancellation inside the loop, and stop the operation with break or a TaskCanceledException.
Demonstrates cancelling with a timeout using a cancellation token and the cancel after method to automatically cancel a long running task after a set timespan, such as five seconds.
Explore creating finished tasks for unit testing by returning already completed, with an exception, or canceled tasks in synchronous methods with async signatures, using Task.FromResult, Task.FromException, and Task.FromCanceled.
Show how synchronization context preserves execution on the original UI thread after an await in UI frameworks, using await, async, and tasks.
Explore how ConfigureAwait(false) bypasses the synchronization context, letting continuations run on a different thread. Understand when capture context matters and why it has no effect on net core.
Explore the retry pattern in asynchronous code with delayed retries and configurable retry counts. Encapsulate the logic in a generic method that accepts a function and returns a result.
learn the only-one pattern in c# to run multiple asynchronous calls, return the first result, and cancel the rest with a cancellation token and task.whenany.
Learn to take control of a task's status using TaskCompletionSource by implementing evaluate value logic that completes, cancels, or faults a task based on input.
Master how to cancel non cancellable tasks in C# by using a task completion pattern and a with-cancellation extension, leveraging cancellation tokens and OperationCanceledException.
Evaluate using value task versus task in C# concurrency by measuring performance; use value task only when results are synchronous or high-demand scenarios justify it, with continuation and caching limits.
Explore how asynchronous programming avoids blocking the UI using Task and await, manage tasks with Task.WhenAll and Task.WhenAny. Learn progress reporting, cancellation tokens, and configuring awaits within a synchronization context.
Explore asynchronous streams in C#, returning sequences of dynamically generated values with async enumerable. Learn about the innumerable interface, the geo keyword, and how to cancel asynchronous streams.
Learn how the IEnumerable interface enables iterating over collections and how yield creates a stream of values over time. Examine differences between synchronous iteration and asynchronous streams, with foreach examples.
Explore asynchronous streams in C# by using the async enumerable interface to iterate data without blocking the user interface, handling paginated web service results efficiently.
Explore two approaches to canceling asynchronous streams, including a break-based method and using a cancellation token with delays, cancellation handling, and resource disposal.
Learn to cancel asynchronous streams produced by IAsyncEnumerable by applying the enumerator cancellation attribute and using with cancellation to pass a cancellation token from the consumer.
Explore how to define asynchronous streams using yield, generate stream values one by one, and cancel asynchronous streams with a cancellation token in C#.
Explore antipatterns in asynchronous programming in C#, naming bad practices like deadlocks, void misuse, and improper cancellation, and emphasize proper async patterns, cancellation, and asynchronous streams.
Learn how blocking an async method with Task.Result on the UI thread creates a deadlock, and avoid it by using await or configuring await to bypass the synchronization context.
Avoid wrapping a synchronous method with an async counterpart; instead expose the synchronous method and let clients decide to use async when appropriate, to preserve scalability.
Explain why async void is dangerous in C#, showing how unhandled exceptions can crash a web application, and demonstrate using async task to safely handle asynchronous operations.
The lecture explains why Task.Factory.StartNew is risky in asynchronous programming, highlighting nested task results and showing that Task.Run offers simpler syntax and safer unwrapping with await.
Dispose cancellation token sources to free resources after timeouts and timers. Use finally or using patterns to auto dispose, whether as a field or inside a method.
Disposing streams in an asynchronous method can cause buffered data to flush synchronously, creating blocking. Use asynchronous disposal and PostAsync to flush the buffer without blocking.
Understand why sync over async can cause deadlocks in methods, and avoid async void, use cancellation source to manage cancellation, and dispose of streams asynchronously to free timers and resources.
Explore parallelism to speed up program processes. Review when not to use parallelism, atomic methods, race conditions, interlocks and locks, and parallel actions on collections.
Divide tasks into parallel parts to save time and fully utilize multicore resources. Measure the cost of parallelism for cpu-bound work like arithmetic or image processing to ensure speed gains.
Explore concurrency in C# by running image downloads and transformations simultaneously with Task.WhenAll, compare sequential versus simultaneous execution, and measure performance improvements.
Learn how Parallel.For executes iterations concurrently in C#, revealing that order is not guaranteed and that parallelism speeds up workloads when tasks can run independently.
Demonstrates parallelism in a CPU-bound matrix multiplication using a parallel for to divide work across threads, boosting processor utilization and speeding up computation.
Explore when to use Task.WhenAll for IO-bound tasks like downloading images and Parallel.For for CPU-bound arithmetic work, leveraging async patterns and parallelism.
Use parallel.forEach to accelerate CPU bound image transformations by processing each image concurrently and saving to a destination folder. Note time gains from sequential to parallel execution.
Parallelism speeds up execution, but incurs setup costs, so measure performance to decide when parallelism pays off; use a mix of parallel and sequential code guided by data.
Invoke different methods in parallel using parallel.invoke to run matrix multiplication and EMS automation simultaneously, demonstrating that unrelated tasks can run in parallel and improve performance.
Learn to cancel parallel operations in C# by using a cancellation token, a cancellation source, and parallel options to stop long matrix multiplications.
Explore how to configure the maximum degree of parallelism in C#, control the number of concurrent threads, and measure its impact on execution time when multiplying matrices in parallel.
Discover atomic methods for safe data sharing in multithreaded C# apps, guaranteeing no intermediate state and consistent results. Achieve atomicity with locks and concurrent collections to avoid data corruption.
Ensure thread-safe methods by preventing data corruption when multiple threads access data. Use interlock or luks, immutable objects, and pure functions that return the same result for the same inputs.
Race conditions happen when multiple threads modify a shared variable without atomicity, leading to nondeterministic results due to read–modify–write sequences; interlocked synchronization can mitigate this.
Learn how Interlocked operations provide atomic updates across multiple threads, preventing race conditions when incrementing a shared value, by using atomic increment and add to ensure thread-safe results.
Use locks to ensure only one thread executes a lock block at a time, preventing race conditions when updating shared values; implement a dedicated mutex and keep the lock short.
ThreadStatic creates a per-thread static field, giving each thread its own copy to avoid interference and safely host non-thread-safe classes, like a per-thread random generator seeded by RNGCryptoServiceProvider.
Learn how PLINQ enables parallel queries on collections with AsParallel, set the degree of parallelism, and use a cancellation token. Maintain original order with AsOrdered after parallel operations.
Learn how to perform aggregates in PLINQ, summing and averaging elements in parallel, and compare sequential versus parallel performance with custom aggregation for matrices.
Process matrix elements as soon as they are ready by using for all with a parallel query, displaying elements to the console as they become available.
Demonstrate parallelism for cpu-bound tasks with parallel for and parallel for each, manage degree of parallelism, cancel operations, and use atomic methods, interlock, lock, and linq for parallel collection processing.
Explore what not to do with parallelism, highlighting when little work doesn't justify it, the risks of race conditions from shared variables, and how to avoid over parallelization and deadlocks.
Measure the impact before parallelizing to ensure productivity. Recognize that parallelism can add thread overhead and may be slower than sequential execution for simple tasks.
Race conditions occur when parallel code increments a variable in a multithreaded context, yielding unpredictable results. Use interlock to make increments atomic, with memory barriers and locks as alternatives.
Explore oversaturation in parallel code when thread count exceeds processor capacity, and learn to avoid nested parallelism such as parallel for inside parallel for to improve efficiency.
Examine why the random class is not thread-safe in multithreaded environments and implement a safe pattern using ConcurrentDictionary with AddOrUpdate and a dedicated lock to synchronize random value generation.
Understand the dangers of using locks in large applications, avoid reusing objects across locks, and prevent deadlocks by using dedicated lock objects and keeping code inside locks simple.
Avoid parallelism for small tasks; when work is limited, overhead slows it below sequential performance. Use locks or interlocks to prevent race conditions and keep code inside the lock simple.
In this course you will learn how to use asynchronous programming and parallelism in C #.
We will look at both patterns and antipatterns of concurrency. That is, we will see what things we should do, but we will also see what things we should not do.
With asynchronous programming we can:
Run a set of I / O tasks at the same time
Prevent the UI of our applications from freezing
Scale up our ASP.NET and ASP.NET Core applications
Cancel tasks so that the user does not have to wait for their completion
Implement generic retry logic
Create asynchronous streams
With parallel programming we can:
Accelerate the execution of certain algorithms
Apply transformations to a set of images in parallel
Use synchronization mechanisms to avoid race conditions
Define the maximum degree of parallelism
Configure instances of a class by threads
Use LINQ in parallel
We'll also see:
Determinism vs Non-Determinism
Handling errors in asynchronous programming
Using Task.WhenAll to wait for the execution of multiple tasks
Reporting progress of multiples tasks
Retry pattern for handling momentaneous errors
Understanding and consuming ValueTask
Using Asynchronous streams
What does it mean for an app to be deadlocked
We will learn all of this in this course!