This covers the asynchronous programming model supported by various programming languages, using the async and await keywords.
Several programming languages support an asynchronous programming model using co-routines, with the async
and await
keywords.
Support for the model was added to
- C# and VB in VS2012
- Python in 3.5
- ECMAScript in ECMAScript 2017
- Rust in 1.39
C# and Visual Studio
Asynchronous programming with async
and await
was introduced with C# 5.0 in Visual Studio 2012. The run-time support for this language concept is a part of .NET 4.5 / Windows Phone 8 / Windows 8.x Store Runtime.
It's also possible to use async/await
and target .NET 4.0 / Windows Phone 7.1 / Silverlight 4 / MonoTouch / MonoDroid / Portable Class Libraries, with Visual Studio 2012+ and Microsoft.Bcl.Async
NuGet package, which is licensed for production code.
Async CTP add-on for VS2010 SP1 is also available, but it is not suitable for product development.
Python
Similar syntax was introduced to Python 3.5 (see PEP 492 - Coroutines with async and await syntax.
Previously, it was possible to write co-routines using generators; with the introduction of await
and async
co-routines were lifted to a native language feature.
ECMAScript
The async
and await
keywords were first reserved in the ECMAScript 2016 specification and then their use and behavior was fully-specified in the ECMAScript 2017 specification.
Examples
Take the following example, first written using Promises. This code chains a set of animations on an element, stopping when there is an exception in animation, and returning the value produced by the final successfully executed animation.
function chainAnimationsPromise(elem, animations) {
var ret = null;
var p = currentPromise;
for (var anim in animations) {
p = p.then(function(val) {
ret = val;
return anim(elem);
})
}
return p.catch(function(e) {
/* ignore and keep going */
}).then(function() {
return ret;
});
}
Already with promises, the code is much improved from a straight callback style, where this sort of looping and exception handling is challenging.
Task.js and similar libraries offer a way to use generators to further simplify the code maintaining the same meaning:
function chainAnimationsGenerator(elem, animations) {
return spawn(function*() {
var ret = null;
try {
for(var anim of animations) {
ret = yield anim(elem);
}
} catch(e) { /* ignore and keep going */ }
return ret;
});
}
This is a marked improvement. All of the promise boilerplate above and beyond the semantic content of the code is removed, and the body of the inner function represents user intent. However, there is an outer layer of boilerplate to wrap the code in an additional generator function and pass it to a library to convert to a promise. This layer needs to be repeated in every function that uses this mechanism to produce a promise. This is so common in typical async Javascript code, that there is value in removing the need for the remaining boilerplate.
With async functions, all the remaining boilerplate is removed, leaving only the semantically meaningful code in the program text:
async function chainAnimationsAsync(elem, animations) {
var ret = null;
try {
for(var anim of animations) {
ret = await anim(elem);
}
} catch(e) { /* ignore and keep going */ }
return ret;
}
This is morally similar to generators, which are a function form that produces a Generator object. This new async function form produces a Promise object.
Trivia
Asynchrony doesn't assume multithreading, async
or await
keywords do not magically create any threads.
Resources:
C#
- Lucian Wischik, video series: Six Essential Tips For Async
- Stephen Toub, video: Task-Based Asynchrony with Async
- Stephen Toub, video: The zen of async: Best practices for best performance
- Stephen Toub and Parallel Team's blog - Async/Await FAQ
- Stephen Cleary's blog - Async and Await
- Stephan Cleary's post - There Is No Thread
- Eric Lippert's blog -
async
-tagged posts - MSDN Magazine - Best Practices in Asynchronous Programming
- MSDN Magazine - It's All About the SynchronizationContext
- MSDN Magazine - Pause and Play with Await
- MSDN Magazine - Async Performance: Understanding the Costs of Async and Await
- MSDN - C# Language Specification for Asynchronous Functions
- MSDN - Task-based Asynchronous Pattern
- MSDN - Whitepaper: Asynchrony in .NET
- Docs - Asynchronous programming (C#)
- Docs - Asynchronous Programming with Async and Await (Visual Basic)