0

Could you please explain what is difference between using async methods inside Linq with/without async/await?

Example

    private async Task<int> MultiplyAsync(int number, int multiplier)
    {
        await Task.Delay(100); // some kind of async operation
        return number * multiplier;
    }

    public async Task DoWorkAsync()
    {
        int multiplier = 2;
        int[] numberArray = new[] { 1, 2, 3, 4, 5 };

        var tasksWithoutAsyncAwait = numberArray.Select(n => MultiplyAsync(n, multiplier));
        var resultWithoutAsyncAwait = await Task.WhenAll(tasksWithoutAsyncAwait);

        var tasksWithAsyncAwait = numberArray.Select(async n => await MultiplyAsync(n, multiplier));
        var resultWithAsyncAwait = await Task.WhenAll(tasksWithAsyncAwait);
    }
  1. What is difference between tasksWithoutAsyncAwait/resultWithoutAsyncAwait and tasksWithAsyncAwait/resultWithAsyncAwait?
  2. Which of these and in what cases should I use?

I tried to find an explanation for this, but without success. Sorry if this has already been discussed.

  • Why should the difference be something else in a foreach loop? IMHO it doesnt matter if called in a foreach or not, the difference is the same. – Rand Random Aug 11 '22 at 09:43
  • @nilsK I think not – Alex Nevajniy Aug 11 '22 at 09:48
  • 1
    @RandRandom Where do you see any hint about `foreach`? – Sebastian Schumann Aug 11 '22 at 09:51
  • Two significant differences. `tasksWithoutAsyncAwait` is easier for the compiler to handle, it just returns the original task. Consequently, if `MultiplyAsync` throws an exception, the stack trace from `tasksWithAsyncAwait` may be easier to interpret. – Jodrell Aug 11 '22 at 10:18
  • 1
    Check out the article [Eliding Async and Await](https://blog.stephencleary.com/2016/12/eliding-async-await.html) by Stephen Cleary. It provides a thorough explanation of the differences. – Theodor Zoulias Aug 11 '22 at 10:41
  • 1
    @SebastianSchumann - LINQ is basically an foreach, LINQ isn't magic – Rand Random Aug 11 '22 at 11:33
  • 1
    @RandRandom Linq is very different from `foreach` because Linq uses deferred execution. If nobody iterates over the results nothing is computed. A `foreach` containing an `await` in its body will execute all calles sequentially whereas the shown code will run them all in parallel. The only difference is the elided async/await in that lambda. But it's an lambda expression and therefore no side effects will occur - if the called async methods return `Task`-instances instead of `ValueTask`s. – Sebastian Schumann Aug 11 '22 at 11:53
  • 1
    @SebastianSchumann - `Linq is very different from foreach` nope – Rand Random Aug 11 '22 at 12:02

0 Answers0