Async-Await | C# Asynchronous Programming

I have seen many experienced professionals, finding it very difficult to understand the async-await. Simple yet powerful feature of .Net framework, that allows the developer to leverage the advantages of the multi core processor and to write a lesser code. Let me start my first blog article with one of my favorite feature of .Net, async-await. I am not going to explain asynchronous programming concepts in detail, but will only focus on usage of aysnc-await keywords.

I will try to summarize the feature with the help of the following example.

Let’s consider a method, that does some complex calculations and takes around 5 seconds.

private static long Loop(long number)
{
	long finalNumber = 0;
	for (long i = 0; i < number; i++)
	{
		finalNumber += i;
	}
	Thread.Sleep(5000); // this is to make method behave like long running method
	return finalNumber;
}

Now we call the method 3 times synchronously, to perform some unrelated operations.

static void Main(string[] args)
{
	Stopwatch sw = new Stopwatch();
	sw.Start();
	Console.WriteLine("Start Sync Call.");

	long output1 = Loop(1000000);
	Console.WriteLine("Output of method 1 - " + output1);

	long output2 = Loop(2000000);
	Console.WriteLine("Output of method 2 - " + output2);

	long output3 = Loop(3000000);
	Console.WriteLine("Output of method 3 - " + output3);

        // Perform some operations 

	sw.Stop();
	Console.WriteLine("Sync Call Complete. Elapsed Time - " + sw.ElapsedMilliseconds);
	Console.ReadKey();
}

The result of the operations can be seen below:

sync call

Now let’s make the method asynchronous by simply changing the return type as show below:

private async static Task<long> LoopAsync(long number)
{
	return await Task.Factory.StartNew(() =>
						{
							long finalNumber = 0;
							for (long i = 0; i < number; i++)
							{
								finalNumber += i;
							}
							Thread.Sleep(5000); // this is to make method behave like long running method
							return finalNumber;
						});
}

The name of the method is changed to append Async, as it is the convention followed for asynchronous methods. Put the same code within Task.Factory.StartNew() method, which makes code to execute in a separate thread. Now that method returns type Task<>, this means method is awaitable. Usage of await keyword means, the execution will return to the caller immediately.

The way we call method also changes, as now return type is Task<> not just long.

static void Main(string[] args)
{
	Stopwatch sw = new Stopwatch();
	sw.Start();
	Console.WriteLine("Start Async Call.");

	var task1 = LoopAsync(1000000);
	var task2 = LoopAsync(2000000);
	var task3 = LoopAsync(3000000);

	// Perform some operations 

	Task.WaitAll(task1, task2, task3);
	Console.WriteLine("Output of method 1 - " + task1.Result);
	Console.WriteLine("Output of method 2 - " + task2.Result);
	Console.WriteLine("Output of method 3 - " + task3.Result);

	sw.Stop();
	Console.WriteLine("Sync Call Complete. Elapsed Time - " + sw.ElapsedMilliseconds);
	Console.WriteLine("Press any key to exit....");
	Console.ReadKey();
}

In code above, I have used Task.WaitAll(….) to keep main thread waiting till asynchronous tasks are completed.

The result of the operations can be seen below:

async-await

Look at the overall time taken to complete all 3 operations. Way lower than what we achieved calling methods synchronously.

Now let’s try to understand what actually async-await has replaced.

Consider the code example below, that executes the normal method to fetch data from database using Task and then wait for the completion of task using ContinueWith method of Task.

private static void SendSMS()
{
	var fetchTask = Task.Factory.StartNew(()=> FetchDataFromDatabaseSync("SMS"));

	// Gather other information required for sending SMS 

	fetchTask.ContinueWith(t => Console.WriteLine("Sent SMS - " + t.Result));

	// Send SMS            
}

private static string FetchDataFromDatabaseSync(string action)
{
	Console.WriteLine("Fetching data for sending " + action);
	Thread.Sleep(5000);
	return action + " Data";
}

Now same can be achieved using async-await in following manner. See the usage of async keyword in method declaration and await in method code.

private async static void SendSMS()
{
	var fetchTask = FetchDataFromDatabaseAsync("SMS");

	// Gather other information required for sending SMS 

	var valueFromTask = await fetchTask;

	// Send SMS
	Console.WriteLine("Sent SMS - " + valueFromTask);
}

private static async Task<string> FetchDataFromDatabaseAsync(string action)
{
	Console.WriteLine("Fetching data for sending " + action);
	await Task.Delay(5000);
	return action + " Data";
}

Try out few examples on your own and you will realize, it is a lot more fun to work with the Tasks.

More info

2 Replies to “Async-Await | C# Asynchronous Programming”

Leave a Reply

Your e-mail address will not be published. Required fields are marked *