且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

为什么异步函数调用两次?

更新时间:2023-02-05 20:01:14

var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i));

创建一个懒洋洋地评估了IEnumerable它映射到数字方法调用的结果。 ReadSensorsAsync 这里没有调用时,它的将会的被评估时调用。

creates a lazily evaluated IEnumerable which maps numbers to method invocation results. ReadSensorsAsync is not invoked here, it will be invoked during evaluation.

这IEnumerable的是两次评估。这里:

This IEnumerable is evaluated twice. Here:

await Task.WhenAll(tasksRead);

在这里:

// Here, another lazy IEnumerable is created based on tasksRead.
var tasksRecord = tasksRead.Where(...).Select(...);  
await Task.WhenAll(tasksRecord);  // Here, it is evaluated.

因此​​, ReadSensorsAsync 被调用两次。

由于csharpfolk的意见建议,物化了IEnumerable应该解决这个问题:

As csharpfolk suggested in the comments, materializing the IEnumerable should fix this:

var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i)).ToList();