I am trying to understand a comment made on a legacy piece of code...
The original code:
public async Task Send(Notification notification)
{
await Task.WhenAll(notification.Methods.Select(async topic =>
{
var client = GetTopicInstance(topic);
var json = JsonConvert.SerializeObject(notification);
var message = new Message(Encoding.UTF8.GetBytes(json));
await client.SendAsync(message); // COMMENT HERE
}));
}
The comment made was this:
Return here instead of using await and change the lambda expression to not have the async modifier. This will truly ensure you are running the SendAsync calls in parallel. Right now, due to the await, it will block at every iteration and every SendAsync will be completed sequentially.
So the revised code looks like this:
public async Task Send(Notification notification)
{
await Task.WhenAll(notification.Methods.Select(topic =>
{
var client = GetTopicInstance(topic);
var json = JsonConvert.SerializeObject(notification);
var message = new Message(Encoding.UTF8.GetBytes(json));
return client.SendAsync(message);
}));
}
What I don't understand is why the second await
would cause blocking.
My understanding is that the WhenAll
creates a Task
for each iteration returned by the Select
. The original code would appear (to me) to then create another Task
within each of those Task
s. I am unclear why those child Task
s would cause blocking.