即使只有一个项目,也会触发两个任务,使用async/await和Task.WhenAll

本文关键字:使用 任务 两个 async Task await WhenAll 项目 有一个 | 更新日期: 2023-09-27 18:17:04

我的代码有什么问题?甚至当物品。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;
     } 

即使只有一个项目,也会触发两个任务,使用async/await和Task.WhenAll

基本上,您使用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);
}
(顺便说一下,我强烈建议总是使用大括号。它更防bug…)