Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Workshop: Asynchronous Programming in C# [Custom Workshop Nov 2020]

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:

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.

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:

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
Contains asynchronous methods that get data from the data service (mentioned above).

  • Topics:
    • .ConfigureAwait(false)

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

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()

Unit testing for a data reader library (CSVReader).

  • Topics
    • Unit testing async methods
    • Fake objects with async methods
    • Task.FromResult()
    • Testing for exceptions

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.

Additional Resources

Links to articles, videos, and additional code samples:

Video Series & Articles (by Jeremy)
Each of these has a lot of supporting links:

Related Articles (by Jeremy)

Other Resources
Stephen Cleary has lots of great articles, books, and practical advice.

Stephen Toub has great articles, too (generally with advanced insights).

Additional Links

For more information, visit


Slides, code samples, and hands-on labs for a custom asynchronous programming in C# workshop (November 2020)







No releases published


No packages published