我的代码出了什么问题?即使items.count只有1,DoSomething方法也会被调用两次,计数器等于2.我是否没有正确构造等待或我是否错误地使用了WhenAll?
public async Task<int> Process(string id)
{
var items = await GetItemsAsync(id);
var counter = 0;
var tasks = items.Select(async item =>
{
if (await DoSomething(item))
counter++
});
if (tasks.Count() > 0)
await Task.WhenAll(tasks);
return counter;
}
答案 0 :(得分:13)
您基本上错误地使用Select
。它很懒,还记得吗?所以每次你迭代它(一次为Count()
而一次在WhenAll
)......它会再次给你的代表打电话。
修复很简单:只需实现查询,例如与ToList()
:
var tasks = items.Select(async item =>
{
if (await DoSomething(item))
{
counter++
}
}).ToList();
这样就可以创建一次的任务。实际上,tasks.Count()
现在根本不需要迭代,因为它已经过优化以使用Count
属性。但我仍然使用Any()
代替:
if (tasks.Any())
{
await Task.WhenAll(tasks);
}
(顺便说一下,我强烈建议总是使用大括号。它更具有抗虫性......)