Pab*_*blo 5 c# task-parallel-library async-await
我正在使用线程计时器来做一些定期工作:
private static async void TimerCallback(object state)
{
if (Interlocked.CompareExchange(ref currentlyRunningTasksCount, 1, 0) != 0)
{
return;
}
var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i));
await Task.WhenAll(tasksRead);
var tasksRecord = tasksRead.Where(x => x.Result != null).Select(x => RecordReadingAsync(x.Result));
await Task.WhenAll(tasksRecord);
Interlocked.Decrement(ref currentlyRunningTasksCount);
}
Run Code Online (Sandbox Code Playgroud)
我打电话给定时器async并使用了WhenAll.在每个工作异步功能中,我有一个控制台输出,显示活动.现在的问题是,在第二个定时器事件中,每个异步函数由于某种原因正在工作两次.计时器设置为长时间.该应用程序是Windows控制台类型.是不是Select以某种方式使它运行两次?
Hei*_*nzi 11
这个:
var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i));
Run Code Online (Sandbox Code Playgroud)
创建一个延迟评估的IEnumerable,它将数字映射到方法调用结果.ReadSensorsAsync这里没有调用时,它会评估过程中调用.
此IEnumerable被评估两次.这里:
await Task.WhenAll(tasksRead);
Run Code Online (Sandbox Code Playgroud)
和这里:
// Here, another lazy IEnumerable is created based on tasksRead.
var tasksRecord = tasksRead.Where(...).Select(...);
await Task.WhenAll(tasksRecord); // Here, it is evaluated.
Run Code Online (Sandbox Code Playgroud)
因此,ReadSensorsAsync被调用两次.
正如csharpfolk在评论中建议的那样,实现IEnumerable应该解决这个问题:
var tasksRead = Enumerable.Range(3, 35).Select(i => ReadSensorsAsync(i)).ToList();
Run Code Online (Sandbox Code Playgroud)