An important detail to note is that an asynchronous operation is different from a parallel operation. Using async/await this way allows asynchronous execution, which allows you to start an execution and have a callback (the C#Task) to act on the return, when it is ready.
In your case, by placing the await on each call, you are explicitly saying that you want to wait for the result of the operation before continuing the execution of your method. This is a valid form of async/await use, but it is not the one you are wanting by your question.
An example of implementing your methods just to illustrate what happens:
private async Task<string> GetUrlFromBaseAsync(int i)
{
Debug.WriteLine($"{DateTime.Now:HH:mm:ss}: Iniciando GetUrlFromBaseAsync - {i}");
await Task.Delay(TimeSpan.FromSeconds(2));
Debug.WriteLine($"{DateTime.Now:HH:mm:ss}: Finalizando GetUrlFromBaseAsync - {i}");
return $"https://www.site{i}.com.br";
}
private async Task<string> GetFileBlobStorageAsync(string url)
{
Debug.WriteLine($"{DateTime.Now:HH:mm:ss}: Iniciando GetFileBlobStorageAsync - {url}");
await Task.Delay(TimeSpan.FromSeconds(5));
Debug.WriteLine($"{DateTime.Now:HH:mm:ss}: Finalizando GetFileBlobStorageAsync - {url}");
return string.Empty;
}
So if you run as you put it in the question, it should show in the output a sequential execution, in which each waited for its end to start executing the next:
21:20:47: Iniciando GetUrlFromBaseAsync - 1
21:20:49: Finalizando GetUrlFromBaseAsync - 1
21:20:49: Iniciando GetUrlFromBaseAsync - 2
21:20:51: Finalizando GetUrlFromBaseAsync - 2
21:20:51: Iniciando GetUrlFromBaseAsync - 3
21:20:53: Finalizando GetUrlFromBaseAsync - 3
21:20:53: Iniciando GetFileBlobStorageAsync - https://www.site1.com.br
21:20:58: Finalizando GetFileBlobStorageAsync - https://www.site1.com.br
21:20:58: Iniciando GetFileBlobStorageAsync - https://www.site2.com.br
21:21:03: Finalizando GetFileBlobStorageAsync - https://www.site2.com.br
21:21:03: Iniciando GetFileBlobStorageAsync - https://www.site3.com.br
21:21:08: Finalizando GetFileBlobStorageAsync - https://www.site3.com.br
I’ll give you some examples of simple ways to execute these methods without waiting, but I won’t include loops and the like to facilitate the example, I’ll keep the calls similar to what you put.
One way is this:
var taskUrl1 = GetUrlFromBaseAsync(1);
var taskUrl2 = GetUrlFromBaseAsync(2);
var taskUrl3 = GetUrlFromBaseAsync(3);
await Task.WhenAll(taskUrl1, taskUrl2, taskUrl3);
var taskFile1 = GetFileBlobStorageAsync(taskUrl1.Result);
var taskFile2 = GetFileBlobStorageAsync(taskUrl2.Result);
var taskFile3 = GetFileBlobStorageAsync(taskUrl3.Result);
await Task.WhenAll(taskFile1, taskFile2, taskFile3);
//outras chamadas...
Send(taskFile1.Result, taskFile2.Result, taskFile3.Result);
With the Task.Whenall(), you specify that you want to wait for the execution of several Tasks before continuing to the next step. Output looks like this:
21:27:27: Iniciando GetUrlFromBaseAsync - 1
21:27:27: Iniciando GetUrlFromBaseAsync - 2
21:27:27: Iniciando GetUrlFromBaseAsync - 3
21:27:29: Finalizando GetUrlFromBaseAsync - 1
21:27:29: Finalizando GetUrlFromBaseAsync - 3
21:27:29: Finalizando GetUrlFromBaseAsync - 2
21:27:29: Iniciando GetFileBlobStorageAsync - https://www.site1.com.br
21:27:29: Iniciando GetFileBlobStorageAsync - https://www.site2.com.br
21:27:29: Iniciando GetFileBlobStorageAsync - https://www.site3.com.br
21:27:34: Finalizando GetFileBlobStorageAsync - https://www.site1.com.br
21:27:34: Finalizando GetFileBlobStorageAsync - https://www.site2.com.br
21:27:34: Finalizando GetFileBlobStorageAsync - https://www.site3.com.br
Another possibility, since you have in your example a method using the return of the other, is to execute the two methods of the same index in the same Task:
var task1 = Task<string>.Run(async () =>
{
var url = await GetUrlFromBaseAsync(1);
return await GetFileBlobStorageAsync(url);
});
var task2 = Task<string>.Run(async () =>
{
var url = await GetUrlFromBaseAsync(2);
return await GetFileBlobStorageAsync(url);
});
var task3 = Task<string>.Run(async () =>
{
var url = await GetUrlFromBaseAsync(3);
return await GetFileBlobStorageAsync(url);
});
await Task.WhenAll(task1, task2, task3);
Send(task1.Result, task2.Result, task3.Result);
The output was very similar:
21:35:34: Iniciando GetUrlFromBaseAsync - 1
21:35:34: Iniciando GetUrlFromBaseAsync - 2
21:35:34: Iniciando GetUrlFromBaseAsync - 3
21:35:36: Finalizando GetUrlFromBaseAsync - 2
21:35:36: Finalizando GetUrlFromBaseAsync - 1
21:35:36: Finalizando GetUrlFromBaseAsync - 3
21:35:36: Iniciando GetFileBlobStorageAsync - https://www.site1.com.br
21:35:36: Iniciando GetFileBlobStorageAsync - https://www.site3.com.br
21:35:36: Iniciando GetFileBlobStorageAsync - https://www.site2.com.br
21:35:41: Finalizando GetFileBlobStorageAsync - https://www.site2.com.br
21:35:41: Finalizando GetFileBlobStorageAsync - https://www.site3.com.br
21:35:41: Finalizando GetFileBlobStorageAsync - https://www.site1.com.br
The operation is correct, when we use async/awat the compiler generates a background waiting state. That is, this is done asynchronously, your program is waiting for the task to finish. This makes the program flow is not blocked.
– Luiz
But is there any way to synchronize it?
– Romeu