There are lot of articles available over the internet on this topic. few of them are nicely explained but some makes you confusing on these terms.
Actually I was going through this concept and realized why don't I blog it for you to make it simple in understanding. So let me try to explain Asynchronous Programming with Async and Await in a way I understand.
Async and Await:
These are two keywords of C# and It's introduced in C#5.0 as part of .NET Framework 4.5. These two keywords helps you to write asynchronous programming code (which will see down here) without any delegate, event or threading complex logic. Actually C# does that complex job internally when you use Async and Await.
Looking into below given example, you will realize it is easy and equivalent as normal synchronous programming code.
Before we proceed let me tell you few basic mandates about async and await:
- await can be used only inside async method (method defines with async keyword)
- async methods can use only void, Task or Task<T> as return type.
- A method can not awaited (we can't use await with method call), if method is not async and doesn't return a Task.
- Always use 'Async' as suffix to your async methods. (this is not mandatory but a guideline which helps to differentiate async and normal methods)
Let see the example.
Here I am going to create an async method which returns
void. Only purpose of this method is to enable my method to use await inside
this method.
public async void DoMyCalculation()
{
int primeLimit = 10;
Task<IEnumerable<int>> primeNumsTask = GetPrimeNumbersAsync(primeLimit);
DoSomeTasksHere();
IEnumerable<int> primeNums = await
primeNumsTask;
Console.WriteLine("Sum of all
prime numbers from 1 to " + primeLimit + " is: " +
primeNums.Sum());
}
This method will do lot of tasks/calculation including finding
sum of prime numbers within a limit. Here my purpose is, I want to calculate
sum of prime numbers asynchronously so that it will not stop/interrupt other
tasks which might be written inside DoSomeTasksHere() like methods.
In above method,
Task<IEnumerable<int>> primeNumsTask =
GetPrimeNumbersAsync(primeLimit);
Says, there is async method called ‘GetPrimeNumbersAsync’
which returns an IEnumerable list of prime numbers(int) within the range
provided. But above code actually means, you will get the prime numbers only
when you await the task using below line of code.
IEnumerable<int> primeNums = await primeNumsTask;
Here ‘GetPrimeNumbersAsync’ methods will initiate the
execution and control will be returned to the calling method ‘DoMyCalculation()’
and control will move forward to execute ‘DoSomeTasksHere()’ method as per our
code.
Now let see how we need to define our async method ‘GetPrimeNumbersAsync()’:
public async Task<IEnumerable<int>> GetPrimeNumbersAsync(int limit)
{
Console.WriteLine("Start
GetPrimeNumbersAsync() call");
IEnumerable<int> primeNums = FindPrimeNumbers(limit);
Console.WriteLine("End
GetPrimeNumbersAsync() call");
return primeNums;
}
private IEnumerable<int> FindPrimeNumbers(int limit)
{
Console.Write("PrimeNumbers:");
for (int i = 1; i <= limit; i++)
{
Thread.Sleep(1000);
if (i % 2 == 0)
{
Console.Write(i + " ,");
yield return i;
}
}
Console.WriteLine();
}
So as per the concept, to
define a method async we need to declare method with async keyword and return
type should of Task<T> (In our case it is
Task<IEnumerable<int>>.
That’s all. Here is the
complete code:
namespace TestConsoleApp
{
public class AsyncAwait
{
static void Main(string[] args)
{
Console.WriteLine("Main() call
starts.");
AsyncAwait program = new AsyncAwait();
program.DoMyCalculation();
Console.WriteLine("Main() call
ends.");
Console.ReadLine();
}
public async void DoMyCalculation()
{
int primeLimit = 10;
Task<IEnumerable<int>> primeNumsTask = GetPrimeNumbersAsync(primeLimit);
DoSomeTasksHere();
IEnumerable<int> primeNums = await primeNumsTask;
Console.WriteLine("Sum of all
prime numbers from 1 to " + primeLimit + " is: " +
primeNums.Sum());
}
public async Task<IEnumerable<int>> GetPrimeNumbersAsync(int limit)
{
Console.WriteLine("Start
GetPrimeNumbersAsync() call");
IEnumerable<int> primeNums = FindPrimeNumbers(limit);
Console.WriteLine("End
GetPrimeNumbersAsync() call");
return primeNums;
}
private IEnumerable<int> FindPrimeNumbers(int limit)
{
Console.Write("PrimeNumbers:");
for (int i = 1; i <= limit; i++)
{
Thread.Sleep(1000);
if (i % 2 == 0)
{
Console.Write(i + " ,");
yield return i;
}
}
Console.WriteLine();
}
private void DoSomeTasksHere()
{
Console.WriteLine("DoSomeTasksHere()
call : I am Sleeping.");
Thread.Sleep(10000);
Console.WriteLine("DoSomeTasksHere()
end : I woke up.");
}
}
}
Now
if you run the above program, this is what you will get as output in output
window.
Main() call starts.
Start GetPrimeNumbersAsync() call
End GetPrimeNumbersAsync() call
DoSomeTasksHere() call : I am Sleeping.
DoSomeTasksHere() end : I woke up.
PrimeNumbers:2 ,4 ,6 ,8 ,10 ,
Sum of all prime numbers from 1 to 10 is: 30
Main() call ends.
Done.
Thank you for reading.
Feel free to provide your feedback/comments.
Reference: https://msdn.microsoft.com/en-us/library/hh191443.aspx
Reference: https://msdn.microsoft.com/en-us/library/hh191443.aspx