I have tested 2 pieces of code:
FYI ldocs
is IEnumerable<BsonDocument>
and doAmethodAsync
calls an API.
var tasks = new List<(BsonDocument docs, int status, bool isSuccess)>>();
tasks.AddRange(ldocs.Select(async b => await doAmethodAsync())
result = await Task.WhenAll(tasks.toArray()).configuration(false)
tasks.RemoveAll(task => task.IsCompleted);
And the other same with only one change:
tasks.AddRange(ldocs.Select(b => doAmethodAsync())
I have not great differences about performance for 900 loops (6-8 sec).
For me the correct code is the second because in the first it's waiting each end of API. Am I right to think that?
CodePudding user response:
To simplify, you're asking about the difference between this:
await Task.WhenAll(something.Select(async () => await DoSomethingAsync()).ToArray());
and this:
await Task.WhenAll(something.Select(() => DoSomethingAsync()).ToArray());
for me the correct code is the second because in the first its waiting each end of api?
No, you're misunderstanding the way it works. DoSomethingAsync()
will still get called concurrently, and the resulting tasks will still be completed concurrently. The only difference with the added async/await is that the compiler adds some state machine code into the lambda function so that if an exception is thrown, that lambda will appear on your stack trace.
The performance difference coming from that additional state machine code will be negligible compared to any async operations you're using.
There is often value in having the stack trace show where the async method call happened. It's probably not a big deal in this case, since the await Task.WhenAll()
is just a line away from the method call, so there's no ambiguity about how DoSomethingAsync
was called. But you can imagine scenarios where DoSomethingAsync
is called from various different parts of code, and the resulting tasks are awaited in a completely different method: it might be difficult to figure out what path led to the point where an exception was thrown if that line of code isn't included in the stack trace.