Level: Intermediate
This repository contains slides, code samples and labs for a custom asynchronous programming workshop. Rather than being an end-to-end view of asynchronous programming, this workshop is based on the following set of topics.
-
Getting Results from Async Methods
A look at the right ways to get results from asynchronous methods (and several wrong ways). This includes the importance of freeing the main thread.- Awaiting Tasks
- Task Continuations
- Proper use of Task.Result
- Avoiding Task.GetAwaiter().GetResult()
- Avoiding Task.Wait()
-
Where Continuations Run
A look at where post-await code and task continuations run (i.e. the main thread or somewhere else), and why this is important.- Default behavior for post-await code and task continuations
- The importance of Task.ConfigureAwait()
- Differences for web applications between .NET Core and .NET Framework
-
Unit Testing
A look at writing unit tests for asynchronous methods.- Testing async methods with MSTest
- Easily creating asynchronous fake objects
- Testing for exceptions
-
Status and Exceptions
A look at success and error states, including checking for exceptions and unwrapping AggregateExceptions.- The danger of unobserved exceptions
- Using Task.IsCompleted, Task.IsFaulted
- Catching full exceptions with Task (AggregateException)
- Catching partial exceptions with await
- Dangers of async void methods
- Returning null vs. Task.CompletedTask or Task.FromResult
-
Additional Topics (if time permits)
- Letting asynchrony propagate
- Parallel programming and exceptions
This workshop assumes a good understanding of C# (classes, generics, methods, and interfaces) and a basic understanding of using async/await and Task, including running and awaiting asynchronous methods.
To complete the Labs (i.e., hands-on exercises), you will need to have the following installed:
-
.NET Core 3.1 SDK
https://dotnet.microsoft.com/download
The .NET Core SDK (Software Development Kit) allows you to build .NET applications. -
Visual Studio Code
https://code.visualstudio.com/download
This is a great all-around editor. -
VS Code C# Extension
https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp
This extension to Visual Studio Code adds syntax highlighing and code completion for C#.
As an alternative, you can use Visual Studio 2019 (any edition).
To follow along with the Samples (which include desktop applications, web applications, web services, and unit tests), Visual Studio 2019 (any edition) is recommended. The following workloads should be installed:
- ASP.NET and web development
- .NET desktop development
These are the hands-on portions of the workshop. Labs can be completed with Visual Studio Code or Visual Studio 2019. All labs run on Windows, macOS, and Linux.
- Lab 01 - Recommended Practices and Continuations
- Lab 02 - Unit Testing Asynchronous Methods
- Lab 03 - Working with AggregateException
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.
The Samples folder contains the samples that are shown during the lecture portions. This code is runnable with Visual Studio Code or Visual Studio 2019; however, several of the sample projects are Windows only. (Visual Studio 2019 is recommended due to use of the debugger and integrated unit test runner.)
Data Service
Most of the samples get data from a web service. This service can be found here:
- /Samples/Completed/UnderstandingAsync/PeopleService/
- /Samples/Completed/AsyncDependencyInjection/PersonReader.Service
Note both of the above projects are identical.
The easiest way to start the service is to navigate to the project folder from the command-line (PowerShell, cmd, or bash), and type:
dotnet run
to start the service.
Projects & Relevant Files
UnderstandingAsync/TaskAwait.Library/PersonReader.cs
Contains asynchronous methods that get data from the data service (mentioned above).
- Topics:
- .ConfigureAwait(false)
UnderstandingAsync/Concurrent.UI.Desktop/MainWindow.xaml.cs
Contains the UI logic for a desktop application. It calls methods from the PersonReader class (above).
- Topics
- Awaiting tasks
- Task continuations
- Handling exceptions
- IsCompleted, IsFaulted
- Cancellation
UnderstandingAsync/Concurrent.UI.Web/Controllers/PeopleController.cs
Contains the controller for a web application. The controller calls methods from the PersonReader class (above).
- Topics
- Awaiting tasks
- Task continuations
- Handling exceptions
- IsCompleted, IsFaulted
- Async controllers
AsyncDependencyInjection/PeopleViewer.WebApp.Tests/PeopleControllerTests.cs
AsyncDependencyInjection/PeopleViewer.WebApp.Tests/FakeReaders.cs
Unit testing for a web application controller class.
- Topics
- Unit testing async methods
- Fake objects with async methods
- Task.FromResult()
AsyncDependencyInjection/PersonReader.CSV.Tests/CSVReaderTests.cs
AsyncDependencyInjection/PersonReader.CSV.Tests/FakeFileLoader.cs
Unit testing for a data reader library (CSVReader).
- Topics
- Unit testing async methods
- Fake objects with async methods
- Task.FromResult()
- Testing for exceptions
UnderstandingAsync/Parallel.UI.Web/Controllers/PeopleController.cs
Contains the controller for a web application that retrieves data in parallel.
- Topics
- Parallel programming
- Catching partial excpetions with "await"
- Catching full exceptions by using a task continuation.
Links to articles, videos, and additional code samples:
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#
- Run Faster: Parallel Programming in C#
- Learn to Love Lambdas in C# (and LINQ, ToO!)
- Get Func-y: Delegates in .NET
Related Articles (by Jeremy)
Other Resources
Stephen Cleary has lots of great articles, books, and practical advice.
- Don't Block on Async Code - Stephen Cleary
- Async/Await - Best Practices in Asynchronous Programming - Stephen Cleary
- ASP.NET Core SynchronizationContext - Stephen Cleary
- There Is No Thread - Stephen Cleary
Stephen Toub has great articles, too (generally with advanced insights).
- Do I Need to Dispose of Tasks? - Stephen Toub
- ConfigureAwait FAQ - Stephen Toub
Additional Links
- Running async tasks on app startup in ASP.NET Core (Andrew Lock)
This is a series of articles from the author of the book ASP.NET Core in Action (second edition is currently in production) - AsyncGuidance (David Fowler - Microsoft)
Note the section on using a static factory for asynchronous construction. This may be part of a possible solution. - Background tasks with hosted services in ASP.NET Core (Microsoft Docs)
Some general techniques for background tasks (this may not apply directly).
For more information, visit jeremybytes.com.