So I have a business object that supports a "Save"-method which does some IO to some device. I then have a list of those objects which I want to save asynchronously in a batch. My code now looks like this:
public async Task Save()
{
foreach (var element in Elements)
{
await element.Save();
}
}
Now this results in n
number of awaits, and I know that each await causes a bit of CPU overhead. I want to eliminate this and only have one single await. How do I refactor to achieve this?
Well, you could call Save()
on everything and then await all of them finishing using Task.WhenAll
:
public async Task Save()
{
await Task.WhenAll(Elements.Select(x => x.Save());
}
or if you really don't do anything else, just:
public Task Save()
{
return Task.WhenAll(Elements.Select(x => x.Save());
}
EDIT: If you want to do them serially, use the code you've already got. It's worth noting that the way async/await has been designed, awaiting a call which actually completes synchronously (e.g. a cache hit, or in your case dirty checking) is really cheap. It doesn't need to do any task scheduling, create a continuation or anything like that. You say:
If I have a list of 10000 objects, and only 1 is dirty, I will end up with 9999 unnecessary async-awaits, which I suspect will be significant.
As ever, suspicions about performance bottlenecks are pretty much meaningless - what's important is evidence about performance bottlenecks. Have you tried the existing code and measured the cost? If not, I strongly suggest you do that before changing anything.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With