async/await in .NET

Lakshitha Fernando
3 min readDec 21, 2020

Understand the basics of asynchronous programming

Liran Katz — morioh.com

Assuming everyone has a basic understanding of the definition of asynchronous programming, therefore, I will directly move to the topic.

In this article we will discuss some basics of async, await and I will further share couple of advance topics in a separate blog.

Before we get our hands dirty, let’s discuss few pros and cons of using async programming in C#.

Pros
*
Increase the responsiveness and performance of the application.
* Improve the scalability by reducing memory/thread usage.

Cons
*
If not implemented properly, dead-lock or race condition is inevitable.
* Waiting on resources unnecessarily when applied for none IO operations.
* Difficult to debug the flow of the code.
* Make the code more complex.
* Significant amount of knowledge is required to write correct and appropriate code.

Finally it’s coding time !!!

For the sake of simplicity, I have created a .NET core (3.1) console application.

First, in synchronous way

A model class is created to retrieve and update values which will be used to demonstrate the synchronous and asynchronous operations.

GetWebSite() method will add a delay to each item (But in a real application this would be your IO call which takes a longer time).

When we invoke the ExecuteWithoutAsync() method the result is displayed as follows.

Time elapsed synchronized way

It has taken 3043 milliseconds to execute synchronously.

Now asynchronously

By assuming that we don’t have the provision to modify GetWebSite() method, we can wrap it with Task.Run() to make it as an asynchronous call.
In addition, following changes were made to the code.

1. await is introduced as the compiler needs to wait until the result comes.
2. async is added to mark the method as asynchronous.
3. Return type of the method changed from void to Task (Further read this).

And below is the result.

Time elapsed async way

As you can observe, there is not much of a improvement in aspect of the execution time.

Here is the reason !!

Though we introduced async invocation, each task is waiting for its completion before move to the next line of code.

site = await Task.Run(() => GetWebSite(item));

Therefore, there is not much of a performance improvement gained, but, the rest of the application threads (if we had a UI) are not blocked due to the delay of the program. So, better responsiveness is still achieved.

In order to accomplish lesser execution time the asynchronous code should be executed in parallel.

Parallel Execution

As in the above code, rather waiting on GetWebSite() for each item, all the tasks are added to a task list and executed them parallelly. So, the compiler doesn’t have to wait until each item completes. Notice that await is removed.

List<Task<WebsiteModel>> tasks = new List<Task<WebsiteModel>>();

And when everything is completed, run through the each item and make it display.

var result = await Task.WhenAll(tasks);   

foreach (var item in result)
{ DisplayName(item.Name);
}

And here is the result !!!

Time elapsed in parallel

As you can see, executing the code in parallel took only 563 milliseconds which is more than 5 times faster than run in synchronously (in asynchronous too).

So it is always recommended to apply async/await by considering the genuine usefulness of it’s implementation.

Thanks a lot for your time and I will share few advance topics in async programming in future.

--

--

Lakshitha Fernando

Technical Lead at Camms. A graduate of University of Colombo School of Computing Sri Lanka. Microsoft certified programmer | Traveller | Hiker and Bookworm