In programming, there are many use cases for doing things in an asynchronous way. In almost all cases, it comes down to executing an operation that may take a while, without blocking user interaction or other program execution. Perhaps the most common example of this is making a web request, waiting for its response, then doing something with said response. While you are waiting for the response, the user interface shouldn’t freeze.
This is where asynchronous operations come in. In essence, you tell the computer to “do X, and whenever that’s done, do Y. In the meantime, let me go about my business”. A real life analogy would be heating food in a microwave oven: You put your food in there, tell the oven what to do and to notify you when it’s done. While the oven is doing its thing, you can get on with setting the table. When it’s done, it gives you hot food, which you can then serve.
Callbacks: The Old, Ugly Way
If you are used to Java, you would often implement asynchronous operations by supplying a callback: a function that gets invoked once the operation is completed. You either instantiate and override a class that implements the required callback functions, or implement the interface directly in your class. The code to execute once the operation completes is nested at least two levels deep, or lives in some other method. Your options are to do some cumbersome nesting, or to artificially split up code that is part of the same action.
C# allows you to do both of those, but offers a much tidier approach. Out with the loads of extra classes and interfaces, in with
async Modifier and
In C#, if you want to do asynchronous work, start by adding the
async modifier to the method where you’ll be doing it.
private async void MyMethod()
In this method, you can now use the
await keyword, for example, like the following:
var itemPrice = await api.getPrice(itemId);
The code in this method will execute up to this point, and not go any further until
api.getPrice has finished its work and retrieved a value. Once in it has retrieved the item’s price from wherever, execution of our method continues at the next line, like regular program flow.
At this point you may object, since nothing but a few keywords distinguish the example from a normal synchronous program. The difference lies in the fact that other code is free to run while the awaited call is ongoing. The user interface will not become unresponsive.
async method behaves exactly like a callback would. In contrast to a callback, all our related code gets to stay in one method, and remains easy to follow, much like a normal procedural program.
In this post I will explain how you can implement your own asynchronous methods for a few common use cases: