我这里的代码有什么问题?即使当 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/

10-12 12:43
查看更多