Usually when we run the C# code, each statement executes synchronously; that means, one after another statement, executes sequentially. But, how do we instruct to run the code asynchronously?. For example, watching a video while it is downloading; instead of waiting the video to completely downloaded. Of course, we call it as streaming media; just for this example, I am considering this as an asynchronous operation.
Another well known example of asynchronous operation is, application window will allow to interact even though some background operations are in progress.
We use threads for asynchronous operations. Creating and Managing the Threads require more code to be added into the Program. To simplify this, and instruct to run the code asynchronously; C# has introduced
async keyword instructs to the compiler that the declared method has
await statements inside, and which has asynchronous operations to execute.
async method needs to have an
await statement to instruct to run the code asynchronously. Otherwise, the statements within
async method will execute synchronously.
You need to understand one important thing here is, when we use these keywords, we are instructing to execute the statements in
async method asynchronously. The statements may or may not execute asynchronously; this is purely depending on the way you use statements inside an
There are different ways we can achieve asynchronous execution of code. Through this Article, we are going to discuss it with the help of
await keywords &
async modifier instructs to the compiler that, the function with this modifier has an
await statements inside; which has an asynchronous operations to execute. We can use this modifier with lambda expressions and methods (both named and anonymous methods).
Can we use this
async keyword with all the methods? No. This modifier can be used ONLY with the methods; whose return type is
void. Otherwise, you will see below Error message, when you build your C# program.
Error 1 The return type of an async method must be void, Task or Task<T>
From C# 7.0; async methods can return any type that has an accessible
And also, older versions of C# are not allowed to use this modifier with
Main method. You will get below error message, when you attempt to use
async modifier with
Main method; or an entry point.
Error 1 'Async_Await_Demo.Program.Main(string)': an entry point cannot be marked with the 'async' modifier
Within the asynchronous methods, usually the statements will run asynchronously. By mentioning
await statement in an
aysnc method; we are instructing to run the statements asynchronously. Otherwise, the statements within
async method, executes synchronously. How it manage? This is completely behind the scene of
await keywords. And as I mentioned above, you need to be cautious when you use statements within async method; otherwise, the statements may not run asynchronously; eventhough you use both
await will do? That’s we will discuss in below section.
If you write the asynchronous method, without
await statements within it; the compiler will throw the below Warning message.
Warning 5 This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
await keyword inserts the suspension point in the execution of asynchronous method until the awaited Task completes. That means, the statements after
await statement will not execute until the associated
Task completes it’s execution. But the program control can goes back to the function from where this asynchronous method is called; which allows the execution of the next statements in the called function. This is possible when the associated
Task will execute in asynchronous mode.
Doesn’t it clear? Read carefully one more time, the above paragraph. The
await operator simply instructs to suspends the execution of next statements, within the
async method, until the associated
Task completes. Once the
Task is completed, the asynchronous method resumes the execution where it suspended; that means, the statements after
await statement will continue to execute.
Does it mean,
async method will run in a separate thread? Not necessarily. That is the beauty of this feature. Associated
Task will execute in the current thread or in a separate thread. A separate thread, doesn’t mean a new thread; it is a thread from Thread Pool. .Net framework manage this thread pool, contains managed threads, to allows to execute asynchronous operations.
Does it executes in asynchronous way, every time when we use Tasks? Not really. The tasks may or may not run asynchronously. This is completely depending on the way you write the program code. Through this article, we are going to achieve this by using Task’s
Task classes are useful for asynchronous operation.
Important thing you need to remember is, you can’t use
await keyword with all the statements; you can use this, only with the statements which returns
Task<T> type or
void types (this is for Event handlers). From C# 7.0, we can use these with any type that has an accessible
That said, below statement is invalid; if SayHello() doesn’t return above mentioned types;
The compiler will throw below Error message;
Error 1 Cannot await 'void'
Task<T> are the classes defined in
System.Threading.Tasks namespace, useful for asynchronous operations. It has a Run() method, through which we can instruct the portion of the code or function to run in a separate thread; a threapool’s thread For example, the statement looks like below;
Task.Run( () => SomeFunction() );
From above statement, SomeFunction() will execute in a separate thread, a thread in a thread pool. We can verify whether the Thread is threadpool’s thread or not; by simply adding the below statement. It displays
True, when it is threadpool’s thread; otherwise, it display
May be, I will write a separate article to discuss on Task and Task<T> classes. In our sample program, we are using Task & Task<T> classes to run a function in asynchronous way.
Complete working code
Let’s put all together and our code looks like below. This code was tested in Windows 7 Operating System and developed using Visual Studio 2012 IDE.
static void Main(string args)
// Async demo, one example with Task.Delay() function
Console.WriteLine("====== Async demo ======");
Task task1 = SomeAsync();
Console.WriteLine("Waiting... async function to return.");
// Async demo, another example with Task.Run() function
Console.WriteLine("\n\n====== Async demo - usually run in a separate thread ======");
Task task2 = AnotherAsync();
Console.WriteLine("Waiting... async function to return.");
Console.WriteLine(">>> Random Number: " + task2.Result);
static async Task SomeAsync()
Random r = new Random();
Console.WriteLine(">>> Random number: " + r.Next());
static async Task AnotherAsync()
// Instruct to run some action in a thread pool's Thread.
int result = await Task.Run(() => GetRandomNumber());
static int GetRandomNumber()
Random r = new Random();
for (UInt32 i = 0; i < System.UInt32.MaxValue; i++);
static void SayHello()
Now, this is the time to walk-through the code. It has two
async methods; SomeAsync & AnotherAsync. And it has two normal functions; SayHello & GetRandomNumber.
SomeAysnc is an
async method, which displays the new random number. But, before it displays the random number; it simply delays the execution of the function for 5 seconds, and gives back the control to the called function to allow to execute rest of the statements. It waits for, 5 seconds; before it executes next statements after
await. This is one example of asynchronous operation.
AnotherAsync method is an
async method we have developed, and it simply calls another method GetRandomNumber and it returns the result of the function; which is newly generated random number. But, it requests to execute GetRandomNumber function, in a thread. And
await statement will suspend the execution of the
async method until the thread completes execution. Meanwhile, the control goes back to the called function (in this case, it is Main); and start executing the statements mentioned after the
GetRandomNumber simply returns the random number. I just keep it busy, by putting a long loop to give the feeling that some lengthy operation is in-progress. 🙂
SayHello is simply displays a message.
The important thing, we need to observe here is; the way the functions are executing and the results were shown. We called SayHello after the
async methods. As the
async methods executed asynchronously, you will see the Hello message before the completion of
async methods; in normal case, SayHello will execute ONLY when all the statements (which are mentioned before this method) are executed.
This has been proved that, out program is executing asynchronously.
Another important thing is, we have called
Wait() methods of the
Task; to keep the Main method to wait until the completion of the
async methods. This is important; because the chances are there, the Program terminates before the completion of