A common mistake is to think that asynchronism is synonymous with parallelism.
The use of
async is not always well understood either.
async , by itself, does not make the method (the code that executes) asynchronous.
async only allows the word
await to be used.
What allows certain code to be executed asynchronously is the Task.
The combined use of async / await allows Write / Mix Synchronous and Asynchronous Code Shape sequential.
Each line of code runs sequentially, when a line with
await is encountered the execution of the method is suspended and execution is returned to the calling code. When the asynchronous operation terminates, execution resumes on the next line and proceeds sequentially.
This misunderstanding makes it possible to use
async in methods where it is not necessary:
private async Task<Resultado> MetodoAsync()
return await opAsync();
await if, in that method, you need to do something with the result and / or after the asynchronous operation ends.
If this is not the case, do not use
async , just return to Task.
private Task<Resultado> Metodo()
When you're ready to deal with the result, then yes, use
That said, let's look at each of the methods:
Each of the
GetTaskAsync() calls is made with
await . When executing the first call (
GetTaskAsync(2000) ) the execution is released (the method returns immediately), waiting for it to finish, and then proceeding with the second call (
GetTaskAsync(3000) is only called after
GetTaskAsync(2000) is finished.
wait is not used in the
GetTaskAsync() call, calls are executed immediately one after the other with tasks running in parallel ("concurrent law").
I've simplified the code to try to show that "parallelism" has, in this case, only to do with the moments (instants) in which each call to
GetTaskAsync() is made.
In this situation ( console application ), only the
GetTaskAsync() method needs to be declared
It is the only one that needs to release the execution to allow it to be called again in the
Parallel() method before terminating the previous call.
static class Program
static async Task<string> GetTaskAsync(int timeout)
Console.WriteLine("Task Thread: " + Thread.CurrentThread.ManagedThreadId);
private static void Main()
Console.WriteLine("Main Thread: " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Should be greater than 5000");
Console.WriteLine("Should be less than 5000");
public static void Parallel()
var res1 = GetTaskAsync(2000);
var res2 = GetTaskAsync(3000);
Console.WriteLine("result: " + res1.Result + " " + res2.Result);
public static void NotParallel()
var res1 = GetTaskAsync(2000).Result;
var res2 = GetTaskAsync(3000).Result;
Console.WriteLine("result: " + res1 + " " + res2);
private static void Watch(Action func)
var sw = new Stopwatch();
Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds);