There's a lot of confusion about async/await, Task/TPL, and asynchronous and parallel programming in general. So let's start with the basics and look at how we can call asynchronous methods using Task and then see how the "await" operator can makes things easier for us. Along the way, we’ll look at continuations, cancellation, and exception handling.
Code samples (.NET 8) and slides are included in this repository.
Articles and additional resources: http://www.jeremybytes.com/Demos.aspx#TaskAndAwait
To build and run the code, you will need to have .NET 8 installed on your machine. The demo is a Windows desktop application, so it will run on Windows only.
The demo code has a /Starter and /Completed folder. These have the code in its initial state and finished state, respectively.
/People.Service contains a service (used by the desktop application)
/UsingTask.Library contains the library code that calls the service
- PersonReader.cs contains the asynchronous method used in the desktop application.
/UsingTask.Shared contains the data types 'Person' and 'People'
/UsingTask.UI contains the desktop application
- MainWindow.xaml.cs contains the code behind that is updated for this demo
Visual Studio 2022
The "UsingTask.sln" contains both of the projects listed above. The service needs to be started along with the desktop application. I generally start the service outside of Visual Studio (see "Running the Service" below) and then have the desktop application set to start in the Visual Studio debugger.
Visual Studio Code
In Visual Studio Code, you will want to start the service separately from the desktop application (see "Running the Service"). You can leave the service running while working with the desktop application.
The .NET service can be started from the command line by navigating to the ".../people-demo/People.Service" directory and typing dotnet run
. This provides endpoints at the following locations:
- http://localhost:9874/people
Provides a list of "Person" objects. This service will delay for 3 seconds before responding. Sample result:
[{"id":1,"givenName":"John","familyName":"Koenig","startDate":"1975-10-17T00:00:00-07:00","rating":6,"formatString":null},
{"id":2,"givenName":"Dylan","familyName":"Hunt","startDate":"2000-10-02T00:00:00-07:00","rating":8,"formatString":null},
{...}]
Recorded Presentations
- NDC London - Jan 2016
- Central California .NET - Apr 2016 (extended version)
Additional Materials
- Understanding Asynchronous Programming in C#
(Workshop with additional slides and labs)
Articles
- Task and Await: Consuming Awaitable Methods
- UI Considerations When Using Asynchronous Methods
- Task and Await: Basic Exception Handling
- Task Continuations: Checking IsFaulted, IsCompleted, and Task.Status
- Task.IsCompletedSuccessfully - YAY! (and hmmm)
- Task and Await: Basic Cancellation
- Brownfield Async: Converting IAsyncResult to Task
- Book Review: Parallel Programming with Microsoft .NET
- Book Review: Async in C# 5.0
Video Series
- Playlist: Task and Await in C#
- Part 1: Consuming Asynchronous Methods
- Part 2: Basic Exception Handling
- Part 3: IsFaulted, IsCompleted, and Task.Status
- Part 4: Basic Cancellation
Progress Reporting
- Simple Progress Reporting with Task
- Custom Progress Reporting with Task
- When Progress Reporting Goes Bad: Incremental Progress vs. Cumulative Progress
- Pay Attention to Where You Create Progress Objects
Related Topics
- Learn to Love Lambdas (and LINQ, Too!)
- Get Func-y: Delegates in C#
- T, Earl Grey, Hot: Generics in C#
Experts
Parallel Programming wtih Task