0

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?

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
Frenchy
  • 16,386
  • 3
  • 16
  • 39
  • I would review this [question](https://stackoverflow.com/questions/34755819/async-await-action-within-task-run). Those are definitely not the same thing. – Zer0 May 02 '22 at 15:05
  • @Zer0, thanks for the link, i have missed it...so in conclusion if i have well read (sorry for my english) its always better to keep async/await? i am just lucky to have the same performance, because my calls to API are fast – Frenchy May 02 '22 at 15:09
  • There's more significant differences than just performance. You'll have to dig deeper which is why I just pointed you to a good reference. – Zer0 May 02 '22 at 15:15
  • Take a look at this: [Eliding Async and Await](https://blog.stephencleary.com/2016/12/eliding-async-await.html) – Theodor Zoulias May 02 '22 at 15:26
  • @Zer0 imay be i have forgotten to precise the methodAsync return `Task<(BsonDocument, int, bool)>` sorry for confusion – Frenchy May 02 '22 at 15:32
  • @TheodorZoulias thank for the link very interesting – Frenchy May 02 '22 at 15:41

1 Answers1

4

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.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • Wow almost downvoted because OP named a List as "tasks". That's very confusing because those are _not_ Tasks. My comments missed that and presumed he was asking for the difference between using async/await inside of something like `Task.Run`. Like the difference between `Task.Run(async () => await { ... })` and `Task.Run(() => { ... })` which are wildly different. – Zer0 May 02 '22 at 15:26
  • Yeah, I can understand that. The OP code definitely wouldn't compile. It took a little guess work to read between the lines. – StriplingWarrior May 02 '22 at 15:29
  • @StriplingWarrior sorry for confusion i have forgotten to precise the methodAsync return Task<(BsonDocument, int, bool)> – Frenchy May 02 '22 at 15:32
  • @StriplingWarrior, thank for answer, i understant its not a performance problem but a problem when i have to debug where the problem occurs... – Frenchy May 02 '22 at 15:38
  • C'est pas grave. :-) – StriplingWarrior May 02 '22 at 15:47