Back to: C#.NET Tutorials For Beginners and Professionals
Async and Await in C# with Examples:
In this article, I am going to discuss how to implement Asynchronous Programming using Async and Await in C# with Examples. Please read our previous article where we discussed the basic concepts of Asynchronous and Parallel Programming.
Asynchronous Programming in C#:
Asynchronous programming allows us to have efficient applications where we do not waste resources when they are executed. In this article, we are going to discuss Asynchronous programming. Here, we will look at concepts and patterns for developing effective asynchronous applications. We will start by discussing async, await, and how we avoid freezing the UI. In the next article, we will see the use of Task, which represents a promise of a method of execution that will end in the future. We will talk about how to report Task progress, and how to cancel tasks, and we will also look at some patterns of asynchronous programming.
Async and Await Keyword in C#:
In modern C# code, in order to use asynchronous programming, we need to use async and await keywords. The idea is that if we have a method in which we want to use asynchronous programming, then we need to mark the method with the async keyword as shown in the below image.
For those asynchronous operations for which we do not want to block the execution thread i.e. the current thread, we can use the await operator as shown in the below image.
So, when we use await operator, what we are doing is, we are freeing the current thread from having to wait for the execution of the task. In this way, we are avoiding blocking the current thread that we’re using and then that thread can be used in another task.
Async and await works in any .NET development environment like Console applications, Windows Form applications, ASP.NET Core for Web development, Blazor for interactive web applications, etc. Here, we are going to use a Console Application because it is really simple to use. But anything that we do in the Console Application will be applicable to any .NET development environment like ASP.NET Core.
Example to Understand Async and Await in C#:
Please have a look at the below example. It’s a very simple example. Inside the main method, first, we print that main method started, then we call the SomeMethod. Inside the SomeMethod, first, we print that SomeMethod started and then the thread execution is sleep for 10. After 10 seconds, it will wake up and execute the other statement inside the SomeMethod method. Then it will come back to the main method, where we called SomeMethod. And finally, it will execute the last print statement inside the main method.
using System; using System.Threading; namespace AsynchronousProgramming { class Program { static void Main(string[] args) { Console.WriteLine("Main Method Started......"); SomeMethod(); Console.WriteLine("Main Method End"); Console.ReadKey(); } public static void SomeMethod() { Console.WriteLine("Some Method Started......"); Thread.Sleep(TimeSpan.FromSeconds(10)); Console.WriteLine("\n"); Console.WriteLine("Some Method End"); } } }
When you execute the above code, you will see that after printing SomeMethod Started……, the console window is frozen for 10 seconds. This is because here we are not using asynchronous programming. One thread i.e. the Main thread is responsible for executing the code And when we call Thread.Sleep method the current thread is blocked for 10 seconds. This is a bad user experience.
Now, let us see how we can overcome this problem by using asynchronous programming. Please have a look at the below image. The Thread.Sleep() is a synchronous method. So, we have changed this to Task.Delay() which is an asynchronous method. The Task.Delay() method exactly does the same thing as Thread.Sleep() does.
And, if we want to wait for the task i.e. Task.Delay to be done, then we have to use the await operator. As we said earlier the await operator is going to release the current thread that is running from having to wait for this operation. Therefore, that thread is going to be available for all our tasks. And then after 10 seconds, the thread will be called to the place (i.e. Task.Delay()) in order to run the rest code of the SomeMethod. As we have used await keyword inside the SomeMethod, we must have to make the SomeMethod as asynchronous as using the async keyword.
It is important to realize that await does not mean that the thread will have to be blocked waiting for the operation. Await means the thread is free to go to do another thing and then he will come back when this operation (in our example Task.Dealy i.e. after 10 seconds) is done. The following example code exactly does the same thing.
using System; using System.Threading.Tasks; namespace AsynchronousProgramming { class Program { static void Main(string[] args) { Console.WriteLine("Main Method Started......"); SomeMethod(); Console.WriteLine("Main Method End"); Console.ReadKey(); } public async static void SomeMethod() { Console.WriteLine("Some Method Started......"); //Thread.Sleep(TimeSpan.FromSeconds(10)); await Task.Delay(TimeSpan.FromSeconds(10)); Console.WriteLine("\n"); Console.WriteLine("Some Method End"); } } }
Output:
Now, if you run the above code, then you will see that after printing the Some Method Started when the statement Task.Dealy() executed, it will free the current thread, and then that current thread comes and execute the rest of the code inside the main method. And after 10 seconds again thread come back to the SomeMethod and execute the rest of the code inside the SomeMethod.
So, the bottom line is if you want to have a responsive UI that does not get blocked because of long-running operations, you must use asynchronous programming.
In the next article, I am going to discuss the Task Class in C# with Examples. Here, in this article, I try to explain how to implement Asynchronous Programming using Async and Await in C# with Examples. I hope you enjoy this Async and Await in C# with Examples article.
Guys,
Please give your valuable feedback. And also, give your suggestions about this Async and Await Operator in C# concept. If you have any better examples, you can also put them in the comment section. If you have any key points related to Async and Await Operator in C#, you can also share the same.
Interesting article
well explained. Thank you
Hi Sir,
In the above code we have SomeMethod() and in that there is a line “await Task.Delay(TimeSpan.FromSeconds(10));”, as per this line the execution goes to main method to execute remaining lines of code. If suppose the remianing lines of code or logic in Main method, takes more than 10 seconds. How come the code/ threads will be handled and will SomeMethod() waits more than 10 seconds.
Please answer this qquestion.
Very good!
Awesome explaination, any method that we think will do an asynchronous operation should be marked async, any time-consuming code inside the async method should be marked with await to free up thread & will come back to review if the awaited code has finished.
Can you do asynchronous operations that return data.
/*In the above code we have SomeMethod() and in that there is a line “await Task.Delay(TimeSpan.FromSeconds(10));”, as per this line the execution goes to main method to execute remaining lines of code. If suppose the remianing lines of code or logic in Main method, takes more than 10 seconds. How come the code/ threads will be handled and will SomeMethod() waits more than 10 seconds.*/
No, the SomeMethod() won’t wait for some logic inside Main Method to finish. SomeMethod() will continue just ending the 10 seconds from “await Task.Delay(TimeSpan.FromSeconds(10));”
Try this code, I changed to 3 seconds the task.delay().
class Program
{
static void Main(string[] args)
{
Console.WriteLine(“Main Method Started……”);
SomeMethod();
DateTime time1 = DateTime.Now;
Console.WriteLine(“Starting Loop inside Main Method”);
for(int i=1 ; i <= 10000 ; i++)
{
for(int j =1; j <= 10000 ; j++)
Console.Write("");
}
Console.WriteLine("Ending Loop inside Main Method");
DateTime time2 = DateTime.Now;
TimeSpan totaltime = time2-time1;
Console.WriteLine($"Loop total time : {totaltime.TotalSeconds}");
Console.WriteLine("Main Method End");
Console.ReadKey();
}
public async static void SomeMethod()
{
Console.WriteLine("Some Method Started……");
await Task.Delay(TimeSpan.FromSeconds(3));
//Console.WriteLine("\n");
Console.WriteLine("Some Method End");
}
}
The output is:
Main Method Started……
Some Method Started……
Starting Loop inside Main Method
Some Method End /* This is from SomeMethod() */
Ending Loop inside Main Method
Loop total time : 5.398109
Main Method End
That’s interesting post
The reason why you get that behavior is fire & forget. You are calling async void method which is not awaited so Task.Delay that you are awaiting inside method is only awaited by the SomeMethod, but SomeMethod itself is not awaited so execution is continued
Your article is very easy to read. Thanks you very much!
Well written as usual, though there is one subtle remark: The total amount of time taken to execute the program remains the same in both cases: sync vs async, provided await is used.
I love this article, thank you so much~!
Good article thanks for sharing.