Asynchronous programming is not a new concept and has been around for several years and it is nowadays a new standard in modern frameworks like AspNetCore. This framework is now fully asynchronous and it's not easy to avoid using its async keyword.
I think there is a certain cloud of fear when it comes to asynchronism, developers sometimes feel afraid of using it because they don’t understand how to use it and its best practices.
Another reason for this sense of fear is due to the fact that in the past asynchronous programming was not easy at all indeed. Since the introduction of async/await keywords in C# 5 asynchronous programming has become much easier to work with.
If you are afraid of asynchronism you have come to the right place, there is no need to jump up to me! In this article, I’ll present you with some of the best practices when it comes to async programming in .NET and you’ll see that's not that big of a deal you might think it is.
What is Asynchronous Programming?
“Asynchronous programming is a means of parallel programming in which a unit of work runs separately from the main application thread and notifies the calling thread of its completion, failure or progress.” — Source
The core of asynchronous programming are the
Task objects, which model asynchronous operations. They are supported by the
The await keyword is where the magic happens. It yields control to the caller of the method that performed await, and it ultimately allows a service to be elastic.
Async all the way
When using asynchronous programming you should use it all the way, this means that all your callers should be async. The effort in asynchronous programming can be worthless if you don’t apply it all the way in your code.
In some cases partially asynchronism can outcome worst results that fully synchronous programming, therefore my advice is to go asynchronous all over your entire stack.
This next piece of code is a good example where sync is preferable over async. Here the use of
Task.Result blocks the current thread to wait for the result.
public int MyMethodAsync()
var result = OtherMethodAsync().Result;
return result + 1;
The right way to do this is by using the await keyword to get the result:
public async Task<int> MyMethodAsync()
var result = await OtherMethodAsync();
return result + 1;
Just don’t return async void, trust me
It’s never a good option to use to return void in an async method in .Net, never.
The most common situation where people feel like async void is a good idea is when implementing a fire-and-forget, it isn’t at all. If any exception is thrown in an async void method the process will be stoped.
So instead of using async void you can use the
Task.Run since if any unhandled exception happens the
TaskScheduler.UnobservedTaskException will be triggered.
public void RunFireAndForgetOperation()
}public async Task FireAndForgetAsync()
var result = await RunOperationAsync();
Async/await over Task return
Please take this one with a pinch of salt because when it comes to performance, returning directly a
Task is faster because there is no computation done in the async state machine but with this, you can end up not taking advantage of the async state machine benefits. The StateMachine is a struct created when using the async/await keywords.
So there are several benefits when using the async/await keywords:
- Asynchronous and synchronous exceptions are normalized to always be asynchronous;
- Exceptions thrown will be automatically wrapped in the returned
Taskinstead of surprising the caller with an actual exception;
- The code is easier to modify;
To wrap up, these are some practices that you should follow when it comes to asynchronous programming and there are lots of great resources over the internet that you can use to know more about this subject and enhance your skills.
Asynchronous programming can simultaneously be your best ally along with being your worst enemy, the key to success is to study and understand how to use it properly.
Remember to always look up to understanding how things really work on a deeper level and don’t try to just follow the patterns or you can end up in a Cargo Cult Anti-Pattern.