我这里的代码有什么问题?即使当 items.count 仅为 1 时,DoSomething 方法也会被调用两次,并且 counter 等于 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;
}
最佳答案
基本上,您错误地使用了 Select
。很懒,记得吗?所以每次你迭代它时(一次用于 Count()
,一次用于 WhenAll
)......它会再次调用你的委托(delegate)。
修复很简单:只需具体化查询,例如使用 ToList()
:
var tasks = items.Select(async item =>
{
if (await DoSomething(item))
{
counter++
}
}).ToList();
这样你就可以创建一次任务。事实上,
tasks.Count()
现在根本不需要迭代,因为它已优化为使用 Count
属性。但我仍然会使用 Any()
代替:if (tasks.Any())
{
await Task.WhenAll(tasks);
}
(顺便说一下,我强烈建议总是使用大括号。它更能抵抗错误......)
关于c# - 即使只有一个项目,也会使用 async/await 和 Task.WhenAll 触发两个任务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25191361/