C# Asyc await

C# Asynchronous Programming with async / await

Asynchronous Programming.

One of the things that confuses most developers is asynchronous versus synchronous execution model. So, in this article, I’m going to explain the difference between synchronous and asynchronous execution model and then explain how we can do asynchronous programming with C#.

Synchronous and Asynchronous execution model

Synchronous program execution-

  • In a synchronous program execution model, program is executed line by line, one at a time.
  • When a function is called, programming execution has to wait until the function returns before it continues execution to the next line. 

Let me show you a demonstration of that.

Imagine here we have a piece of code with four lines.In the second line, we are making a call to a function that is going to be a blocking operation. It’s going to be time consuming. An example of that is when we access a database or website. So, as we run this program, you’ll see that each line is going to be green, and you will notice that in the second line there is going to be a delay. Because, you notice that we blocked on the second line. 

Asynchronous program execution-

  • In asynchronous program execution when a function is called, program execution continues to the next line without waiting for that function to complete.

So let’s do another simulation again.

This time you will notice that the second line executes immediately and the control will go to line three and four. In the second line, we provide a callback to that time-consuming process function. So when the execution of that function is finished then that callback function will be called. Let’s take a look.So as you see the program runs more smoothly. We didn’t block on the second line.

So what’s the difference?

  • Asynchronous programming model improves responsiveness of your application.

You have already seen Asynchronous programming’s benefits in the real world-

  1. Think of Windows Media Player or your web browser.In the case of Windows Media Player as it’s playing in media let’s say a song or a movie the UI continues to be responsive.You can resize the window, you can move it around, you can see an animation. If Windows Media Player did not utilize asynchronous programming as it was accessing the file system and reading a piece of music that we know would freeze. You could not touch that window.
  2. Same for your web browser. As a web browser downloads content from the Web the UI is still functioning. It’s responsive  and that’s the benefit of asynchronous programming model.

So when do we use asynchronous programming?

Anytime we have a block in operation such as —

  • accessing the Web.
  • working with files and databases.
  • working with images and so on.

How do we do that Asynchronous programming?

Traditionally in C# we had two common approaches-

  1. Using multithreading,
  2. Using callback methods.

Both these approaches are complex to learn and understand.

So, in.NET Version 4.5 Microsoft introduced a new asynchronous programming model-

  • Async / Await

Which is called Task-based Asynchronous Model and we achieved that by using async and await keywords. And that’s the topic of this article.

So let’s jump into your favourite IDE and learn about async and await. Okay. Here I’ve got a basic console application. First, let’s see how asynchronous operation can affect the responsiveness of our application. So, I’m going to create a method here DownloadHtml (line 18) that takes a url. We’re going to use the WebClient (line 20) then, get the Html and that URL using DownloadString method (line 21) here. So, DownloadString takes a URL and returns a string which in this case is in Html. Now, we need to write that Html to a file on the disk. So let’s use StreamWriter (line 22) for writing that Html to disk and I’m going to store it in a file here called result. html in my projects folder, it doesn’t really matter and here we use streamWriter.write (line 24) to write that html to this file.

using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("step 1: Start Fetching Html");
            Console.WriteLine("step 2: Fetching...");
            DownLoadHtml("https://99coding.club/");
            Console.WriteLine("step 3: finished");
        }
     
        public static void DownLoadHtml(string url)
        {
            var webClient = new WebClient();
            var html = webClient.DownloadString(url);
            using (var streamwtr=new StreamWriter("/path/to/outputfile/output.html"))
            {
                streamwtr.Write(html);
            }
        }
    }
}

Pretty simple, right? Now,  pass an address like “https://99coding.club”. Let’s run this application. 

Notice that, it’s going to take a couple of seconds until we download that Html and during that time the cursor in output terminal going to be freeze or unresponsive, which means, There was a tiny delay here. So the delay depends on the operation.The longer the operation the more unresponsive the UI is going to be.

Now, let’s see how we can improve these by using an asynchronous operation. So, I’m going to write an asynchronous version of this DownloadHtml method.

using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;

namespace Async
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("step 1: Start Fetching Html");
            Console.WriteLine("step 2: Fetching...");
            DownLoadHtmlAsync("https://99coding.club/");
            Console.WriteLine("step 3: finished");
        }
        
        public static async Task DownLoadHtmlAsync(string url)
        {
            var webClient = new WebClient();
            var html = await webClient.DownloadStringTaskAsync(url);
            
            using (var streamwtr=new StreamWriter("/Users/sajidMacPro/RiderProjects/AdvanceCSharp/result.html"))
            {
                await streamwtr.WriteAsync(html);
            }
        }
    }
}

Line 18: We start with public All the asynchronous methods should be decorated with the async keyword. So, we put async here. Now, for the return type we need to return a Task object.

What is a TaskA Task is an object that encapsulates the state of an asynchronous operation. It comes in two forms. One is the non-generic formwhich is user here and another is generic form. So, if your method returns, let’s say a string, you need to use the generic version of the Task. So, that would be Task of string.  Task<string> . If your method is void, you need to use the non-generic version of Task which is just this one here.

So, you return Task here. Now we name our method DownloadHtml and by convention we need to add the async suffix. You don’t have to but this is the recommended practice from Microsoft. Then, we’re going to use the same parameter here.  public static async Task DownLoadHtmlAsync(string url) Well, at this point, this method is still not asynchronous. All we have done is, we changed the declaration of the method, what we’re essentially calling asynchronous blocking operation in line 21 and line 25. So we need to change these two blocking operations to asynchronous ones.

Now, since .NET 4.5 pretty much most methods that are blocking operations have an asynchronous or nonblocking version and they all end with the async suffix.

Line 21 : In the WebClient class we have DownloadString which is the synchronous versions. We have TaskAsync and Async-

DownloadStringAsync method here is a legacy one and it’s got nothing to do with the new asynchronous programming model in .NET 4.5. So, DownloadStringTaskAsync is the one we’re going to use. As you see,it returns a Task<string> because the original method returned a string.

Now the asynchronous version returns a Task of a string. So you’re going to use this method here.And typically, when we call an asynchronous method that returns a Task we need to put an await operator before that asynchronous method call . What does it mean?

In the first glance, it may give you the impression that the program execution has to wait for this method to complete. But that’s not the case at all. await is just a marker for the compiler. So when the compiler sees that, it knows that this operation is going to be costly and it may take a bit of time. In that case, instead of blocking this thread, it’s going to return the control immediately to the caller of this method here in line 14. So the thread here is not going to be blocked and the control immediately returns here. Which means that the UI immediately becomes responsive.

Now, at some point, this method DownloadStringTaskAsync is going to be completed and the runtime is going to be aware of that because we marked this with await (line 21) var html = await webClient.DownloadStringTaskAsync(url);So when this method is completed runtime comes back here and executes the rest of DownLoadHtmlAsync method.

So the interesting thing here is if you look, compare these two methods DownloadString and DownloadStringTaskAsync , they look pretty much the same. Except, in DownloadStringTaskAsync method we have an awaitwhereas we don’t have that here in the original synchronous version. But at runtime, how this code is executed looks different.

We as programmers do not have to partition our code in terms of functions and their callbacks and we are giving this hard task to the compiler by using the async and await keywords.

Line 25:  this StreamWriter has a Write method here which is again a blocking operation. So we can improve the responsiveness of our application even further by using the asynchronous version of Write method.

So, look, we have WriteWriteAsync, WriteLine and WriteLineAsyncSo pretty much, as you see for all synchronous methods we have an asynchronous version. I’m going to use the WriteAsync one and as I explained, we need to put await here to let the compiler know that this method is going to take some time. So it returns to control immediately and the executing thread is not going to be blocked.

let me run the asynchronous version of this application and see how it makes a difference –

So notice that, this time step 2 not going to be frozen and it can immediately move to step 3. See, it’s very responsive!

Use case for asynchronous programming –

  • If you’re building WPF applications or applications for the Windows Runtime, wherever you have blocking operations like accessing files, accessing database, calling Web services or accessing Web. 

 

  • Accessing the calendar, address book, on a mobile all of these are blocking operations and you can improve the responsiveness of your application by using async and await.

 

  • What about Web applications like asp.net mvc applications. Well, in those applications, the UI is not in the same process. It’s on the client’s machine, in the browser. So does the new async programming model improve web applications? Yes. How? Well, typically in a web application, when a request comes to the server a thread is allocated to handle that request. Now, during execution of that request if there is a blocking operation that thread is going to be busy. And each machine as we know has a limited number of threads. So if we have a lot of concurrent connections and all our threads are busy waiting for a blocking operation that server becomes unresponsive. The only way is to add more servers which is scaling out. 

We can improve this by using an asynchronous model. So when a thread has to execute a blocking operation the control immediately returns to the thread and that thread can be used to handle another request. When that blocking operation completes execution, again the same thread or another thread will come back here and pick up the rest of the program and continue execution. So with asynchronous model, we can scale up instead of scaling out.

That doesn’t mean that if you design your application poorly this is going to help you significantly. Not at all. But this is just a recommended practice so whenever you are using blocking operations you should use async and awaitWell, that’s pretty much it for this article. I hope you enjoyed, and thank you for reading.

 

Leave a Reply

Your email address will not be published. Required fields are marked *