Full-day Workshop
To download just the labs, you can visit this repository:
https://github.com/jeremybytes/async-workshop-labs-only-2024
This project contains slides and code samples for the "Asynchronous and Parallel Programming in C#" workshop with Jeremy Clark.
Level: Intermediate
Asynchronous programming is a critical skill to take full advantage of today's multi-core systems. But async programming brings its own set of issues. In this workshop, we'll work through some of those issues and get comfortable using parts of the .NET Task Parallel Library (TPL).
We'll start by calling asynchronous methods using the Task Asynchronous Pattern (TAP), including how to handle exceptions and cancellation. With this in hand, we'll look at creating our own asynchronous methods and methods that use asynchronous libraries. Along the way, we'll see how to avoid deadlocks, how to isolate our code for easier async, and why it's important to stay away from "async void".
In addition, we'll look at some patterns for running code in parallel, including using Parallel.ForEachAsync, channels, and other techniques. We'll see pros and cons so that we can use the right pattern for a particular problem.
Throughout the day, we'll go hands-on with lab exercises to put these skills into practice.
Objectives:
- Use asynchronous methods with Task and await
- Create asynchronous methods and libraries
- How to avoid deadlocks and other pitfalls
- Understand different parallel programming techniques
Basic understanding of C# and object-oriented programming (classes, inheritance, methods, and properties). No prior experience with asynchronous programming is necessary; we'll take care of that as we go.
Attendee Requirements:
-
You must provide your own laptop computer (Windows or Mac) for this hands-on lab.
-
You need to have the .NET 6 SDK or .NET 8 SDK installed as well as the code editor of your choice (Visual Studio 2022 Community Edition or Visual Studio Code are both good (free) choices).
-
Interactive labs, web application samples, and console samples will work with Windows, macOS, and Linux (anywhere .NET 6/8 will run).
-
WPF desktop samples will only work on Windows machines. There are equivalent web and console examples for these projects.
Links:
-
.NET 8.0 SDK
https://dotnet.microsoft.com/en-us/download -
Visual Studio 2022 (Community)
https://visualstudio.microsoft.com/downloads/ Note: Install the "ASP.NET and web development" workload for the labs and samples. Include ".NET desktop development" for "digit-display" sample and WPF-based samples. -
Visual Studio Code
https://code.visualstudio.com/download
The sample code use .NET 6 or .NET 8. The console and web samples will run on all Window, macOS, and Linux versions that support .NET. The desktop samples are Windows-only.
Samples have been tested with Visual Studio 2022 and Visual Studio Code.
All samples require the "Person.Service" web service be running. To start the service, navigate to the "Person.Service" folder from the command line and type "dotnet run".
Ex:
C:\understanding-async\People.Service> dotnet run
The service can be found at http://localhost:9874/people
The "DemoCode" folder contains the code samples used in the workshop.
Shared Projects
- People.Service
A web service that supplies data for the sample projects. - TaskAwait.Shared
A library with data types that are shared across projects (primarily the "Person" type). - TaskAwait.Library
A library with asynchronous methods that access the web service. These methods are called in the various applications detailed below.
Relevant file: PersonReader.cs
Concurrent Samples
The Concurrent samples run asynchronous methods, get results, handle exceptions, and support cancellation (unless otherwise noted).
- Concurrent.UI.Console
A console application (Windows, macOS, Linux)
Relevant file: Program.cs - Concurrent.UI.Desktop
A WPF desktop application (Windows only).
Relevant file: MainWindow.xaml.cs - Concurrent.UI. Web
A web application (Windows, macOS, Linux).
Note: this application does not support cancellation.
Relevant file: Controllers/PeopleController.cs
Parallel Samples
The Parallel samples use Task to run asynchronous methods in parallel - also get results, handle exceptions, and support cancellation (unless otherwise noted).
- Parallel.Basic
A console application that does not support cancellation or error handling (Windows, macOS, Linux).
Relevant file: Program.cs - Parallel.UI.Console
A console application (Windows, macOS, Linux).
Relevant file: Program.cs - Parallel.UI.Desktop
A WPF desktop application (Windows only).
Relevant file: MainWindow.xaml.cs - Parallel.UI. Web
A web application (Windows, macOS, Linux).
Note: this application does not support cancellation.
Relevant file: Controllers/PeopleController.cs
Progress Reporting (Bonus Material)
The Progress Reporting samples show how to report progress from an asynchronous method - in this case, as a percentage complete. These also get results, handle exceptions, and support cancellation.
- ProgressReport.UI.Console
A console application that reports percentage complete progress through text. Ex: "21% Complete". (Windows, macOS, Linux)
Relevant file: Program.cs - Parallel.UI.Desktop
A WPF desktop application that reports percentage complete progress through a graphical progress bar. (Windows only)
Relevant file: MainWindow.xaml.cs - TaskAwait.Library
This shared library contains a method that supports progress reporting.
Relevant method:
public async Task<List<Person>> GetPeopleAsync(IProgress<int> progress,
CancellationToken cancelToken = new CancellationToken()) {...}The "Labs" folder contains hands-on labs. The labs are integrated throughout the workshop day.
- Lab 01 - Recommended Practices and Continuations
- Lab 02 - Adding Async to an Existing Application
- Lab 03 - Parallel Practices
- Lab BONUS - Working with AggregateException
- Lab BONUS - Unit Testing Asynchronous Methods
Each lab consists of the following:
-
Labxx-Instructions (Markdown)
A markdown file containing the lab instructions. This includes the scenario, a set of goals, and step-by-step instructions.
This can be viewed on GitHub or in Visual Studio Code (just click the "Open Preview to the Side" button in the upper right corner). -
Starter (Folder)
This folder contains the starting code for the lab. -
Completed (Folder)
This folder contains the completed solution. If at any time, you get stuck during the lab, you can check this folder for a solution.
Related Articles (by Jeremy)
- Why Do You Have to Return "Task" Whenever You "await" Something in a Method in C#?
Article
Video - Don't Use "Task.WhenAll" for Interdependent Tasks
- Looking at Producer/Consumer Dependencies: Bounded vs. Unbounded Channels
- Producer/Consumer Exception Handling - A More Reliable Approach
- "await.WhenAll" Shows 1 Exception - Here's How to See Them All
Video Series & Articles (by Jeremy)
Each of these has a lot of supporting links:
- I'll Get Back to You: Task, Await, and Asynchronous Programming in C# (Includes progress reporting)
- Run Faster: Parallel Programming in C#
- Learn to Love Lambdas in C# (and LINQ, ToO!)
- Get Func-y: Delegates in .NET
BackgroundWorker Component
- BackgroundWorker Component and .NET 6
- BackgroundWorker Component - "I'm not Dead, Yet!"
- Keep Your UI Responsive with the BackgroundWorker Component
Other Resources
Stephen Cleary has lots of great articles, books, and practical advice.
- .NET 8 - ConfigureAwait in .NET 8 - Stephen Cleary
- Don't Block on Async Code - Stephen Cleary
- Async/Await - Best Practices in Asynchronous Programming - Stephen Cleary
Stephen Toub has great articles, too (generally with advanced insights).
- Do I Need to Dispose of Tasks? - Stephen Toub
- Understanding the Whys, Whats, and Whens of ValueTask - Stephen Toub
Articles / Videos Suggested by prior Workshop Attendees
- ASP.NET Core SynchronizationContext by Stephen Cleary
- ConfigureAwait FAQ by Stephen Toub
- There Is No Thread by Stephen Cleary
- C# Async/Await/Task Explained (Deep Dive) Video by Raw Coding
For more information, visit jeremybytes.com.