diff --git a/docs/csharp/asynchronous-programming/async-scenarios.md b/docs/csharp/asynchronous-programming/async-scenarios.md index 7246ade88a18b..e72592944ddfc 100644 --- a/docs/csharp/asynchronous-programming/async-scenarios.md +++ b/docs/csharp/asynchronous-programming/async-scenarios.md @@ -130,7 +130,27 @@ You can write this code more succinctly by using LINQ: :::code language="csharp" source="snippets/async-scenarios/Program.cs" ID="GetUsersForDatasetByLINQ"::: -Although you write less code by using LINQ, exercise caution when mixing LINQ with asynchronous code. LINQ uses deferred (or lazy) execution. Asynchronous calls don't happen immediately as they do in a `foreach` loop, unless you force the generated sequence to iterate with a call to the `.ToList()` or `.ToArray()` method. This example uses the method to perform the query eagerly and store the results in an array. This approach forces the `id => GetUserAsync(id)` statement to run and initiate the task. +Although you write less code by using LINQ, exercise caution when mixing LINQ with asynchronous code. LINQ uses deferred (or lazy) execution, which means that without immediate evaluation, async calls don't happen until the sequence is enumerated. + +The previous example is correct and safe, because it uses the method to immediately evaluate the LINQ query and store the tasks in an array. This approach ensures the `id => GetUserAsync(id)` calls execute immediately and all tasks start concurrently, just like the `foreach` loop approach. + +**Problematic approach** (without immediate evaluation): + +```csharp +// DON'T do this - tasks won't start until enumerated. +var getUserTasks = userIds.Select(id => GetUserAsync(id)); // No .ToArray()! +return await Task.WhenAll(getUserTasks); // Tasks start here. +``` + +**Recommended approach**: + +```csharp +// DO this - tasks start immediately. +var getUserTasks = userIds.Select(id => GetUserAsync(id)).ToArray(); +return await Task.WhenAll(getUserTasks); +``` + +Always use or when creating tasks with LINQ to ensure immediate execution and concurrent task execution. ## Review considerations for asynchronous programming