It:
var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i));
creates a lazily evaluated IEnumerable that maps numbers to the results of a method call. ReadSensorsAsync is not called here, it will be called during the evaluation.
This IEnumerable is evaluated twice. Here:
await Task.WhenAll(tasksRead);
and here:
// Here, another lazy IEnumerable is created based on tasksRead. var tasksRecord = tasksRead.Where(...).Select(...); await Task.WhenAll(tasksRecord); // Here, it is evaluated.
Thus, ReadSensorsAsync is called twice.
As csharpfolk suggested in the comments, IEnumerable materialization should fix this:
var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i)).ToList();
source share