As a developer, I often do File Operations like writing and reading
to and from a file, performing file Uploads and Downloads to and from a file
server and so on. In such scenarios, if the size of the file is huge and if
number of files to be uploaded and downloaded are more than what can be managed
by the application, I go in for Asynchronous programming using BeginInvoke()
method of the delegate. In this case, it is necessary for me to implement complex
threading mechanisms which can at times make my code complex and a difficult to
maintain.
However, when I came across the new features in.NET Framework 4.5 and
C# 5.0, I found a simple solution. The developer community has been provided
with a new simplified approach for Asynchronous
programming which can make a developer’s life simpler. Following are the
new Keywords introduced:
async: This modifier indicates the method is now
asynchronous. The benefit of using this keyword is that it provides a simpler
way to perform potentially long-running operations without blocking the callers
thread. The caller of this 'async' method can resume its work without waiting
for this asynchronous method to finish its job. This reduces developer’s
efforts for writing an additional code. The method with 'async' modifier
has at least one await.This method now runs synchronously until
the first await expression written in it.
await: Typically, when a developer writes some code
to perform an asynchronous operations using threads, then he/she has to
explicitly write necessary code to perform wait operations to complete a task.
In asynchronous methods, every operation which is getting performed is called a
Task. Here the task is also known as an ongoing work or work
to perform.
The ‘await’ keyword is applied on the task in an asynchronous method
and suspends the execution of the method, until the awaited task is not
completed. During this time, the control is returned back to the caller of this
asynchronous method.
You must keep in mind that the keyword ‘async’ is applied on the
method which is decorated with the ‘async’ keyword. The most important behavior
of the await keyword is it does not block the thread on which it is
executing. What it does it that it signals to the compiler to continue with
other async methods, till the task is in an await state. Once the task is
completed, it resumes back where it left off from.
Let's take an example to understand it.
class
Program
{
static void Main(string[] args)
{
Console.WriteLine(string.Format("Step1: Please enter a number"));
string userInput = Console.ReadLine();
Console.WriteLine("---------
Ex1: Synchronous Call: ---------");
CallSync(userInput);
Console.WriteLine(string.Format("Ex1 - Step3: Synchronous call finished"));
Console.WriteLine("---------
Ex2: Asynchronous Call: ---------");
CallAsync(userInput);
Console.WriteLine(string.Format("Ex2 - Step3: Asynchronous call finished"));
Console.WriteLine(string.Format("Ex2 - Step4: Other operations can now be done"));
Console.ReadLine();
}
#region Synchronous Call
public static void CallSync(string userInput)
{
long result = SyncFactorial(ulong.Parse(userInput));
Console.WriteLine(string.Format("Ex1 - Step2: Factorial is {0}",
result.ToString()));
}
public static long SyncFactorial(ulong
number)
{
long result = 1;
for (long i = 1; i
<= number; i++)
{
// Simulated a time consuming operation
Thread.Sleep(1000);
result *= i;
}
return result;
}
#endregion
#region Asynchronous Call
public static async void CallAsync(string userInput)
{
long result = await AsyncFactorial(long.Parse(userInput));
Console.WriteLine(string.Format("Ex2 - Step2: Factorial is {0}",
result.ToString()));
}
public static async Task<long>
AsyncFactorial (long number)
{
Task<long> resultFactorial
= TaskEx.Run(() =>
{
long result = 1;
for (long i = 1; i
<= number; i++)
{
// Simulated a time consuming operation
Thread.Sleep(1000);
result *=
i;
}
return result;
});
return await resultFactorial;
}
#endregion
}
Explanation : As shown in above example I have wrote a two methods.
1) First
is "SyncFactorial"
this is coded like traditional way and I have added some sleep of a second so
method can take more time to execute and we can easily understand how execution
is done.
2) Second is "AsyncFactorial" this is coded in a such a
fashion that code will run on separate thread with use of 'Async' and if you
see same code is there what we have written in "SyncFactorial" but the
only difference is - we have created that as Task to perform it as asyncronous
and I have added 'await' statement for resultFactorial and second at method
calling "AsyncFactorial" So when function is call at time Task is
created and run on different thread and caller is free now to execute further
line of code and when task completed its task then it will start from await
statement in our case it will be await for result and main thread continues
with Console.WriteLine statement.
Now let's see execution sequence of the program.
Step1: Please enter a number : 5
--------- Ex1: Synchronous Call: ---------
Ex1 - Step2: Factorial is 120
Ex1 - Step3: Synchronous call finished
--------- Ex2: Asynchronous Call: ---------
Ex2 - Step3: Asynchronous call finished
Ex2 - Step4: Other operations can now be done
Ex2 - Step2: Factorial is 120
We can archive this functionality with some more amount of code using
threading but using 'Async' and 'Await' it is very easy to code asynchronous.
Conclusion: The new keywords 'async' and 'await' introduced in C# 5.0 helps
developers to make their asynchronous programming logic less complex and more
manageable.
No comments:
Post a Comment