Much of our programming model is based upon the simple concept of putting data into a variable. This sort of programming typically goes by the term “imperative programming”. We are issuing a series of commands; the computer executes the commands.
These commands typically are run in some very predictable order. Early programming languages even had line numbers. Code issued ran each line of code, one line after another. It would start at line 1, then go to line 2, etc.
Now programs could jump around, and in the early days, this would often use some sort of goto command. But eventually, many higher-level languages had additional options. We had more structure options, such as ifs, switches, and methods/functions. But with this structure, we still ran code in a very linear fashion. When you call a method or function, your code returns to the same location.
Asynchronous (async) code doesn’t necessarily behave that way. With async code, we add a lot of complexity where the code doesn’t necessarily run in a nice linear fashion.
Why would we add the complexity of async code? If it is harder to understand, why?
Well, it has an advantage in that it will better respect the way I/O operations occur. This async model tends to better represent programming when our code is interacting with outside systems. The closer alignment of code to system behavior makes it perform better for I/O heavy operations.
Using these keywords, we can make async code look almost like synchronous code again. And it even makes it easier to read!
Async/await are not a silver bullet, but many languages now support them because it does make working with async code easier. This change to .NET was very welcome. It greatly impacted how we write code today.
.NET Framework 2.0 (Generics, Partial Classes, Nullable Types, Anonymous Methods)
.NET Framework 3.0/3.5 (WPF, WF, WCF, Auto-Implemented Properties)
.NET Framework 3.0 (LINQ)
.NET Framework 3.5 SP1 (ADO.NET Entity Framework)
.NET Framework 4.0 (Parallel, Dynamic)
.NET Framework 4.5 (Async)
.NET Core 2.0/2.1
.NET Core 3.0/3.1
.NET Core 5