为什么我们应该避免在 C# 循环中使用 await

3203c50ece08df756d3509af9a9c30dc.png

在本文中,我们将探讨在循环中使用关键字的正确场景以及何时避免使用它。

循环中的基本操作

循环遍历特定方法,直到满足特定条件。尽管在循环中使用可能看起来很吸引人,但如果等待的方法可以并发运行,而忽略循环的固有特性,则可能会产生不利影响。有关异步编程的更多信息,请参阅我们的文章:如何异步执行多个任务。await

当我们在循环中添加 await 时会发生什么?

通过在我们的循环中使用,我们暂停迭代以允许等待的方法执行,然后继续进行下一次迭代。这意味着我们正在同步执行循环内部的操作。

public static async Task<List<int>> ResultAsync(int delayMilliseconds = 1000)
{
    var numbers = new List<int> { 10, 20, 30, 40, 50, 60, 70, 80, 90 };    var result = new List<int>();
    foreach (var number in numbers)
    {
        Console.WriteLine($"Processing {number}");
        await Task.Delay(delayMilliseconds);
        Console.WriteLine($"Processed {number}");
        result.Add(number);
    }
    Console.WriteLine("Done Processing");
    return result;
}

在这里,我们添加了方法。这意味着我们必须等待完成,然后才能继续进行下一次迭代。

在循环中使用可确保元素按顺序执行。但是,这也意味着完成整个迭代可能需要很长时间。

现在,让我们看一下控制台输出:

Processing 10  
Processed 10  
Processing 20  
Processed 20  
...  
Done Processing

我们观察到,该程序按照列表中提供的顺序正确处理数字。

避免 Await in 循环以使它们异步

既然我们知道在循环中使用可以使其同步,那么我们可以探索如何使我们的循环异步。这是使用 .简单来说,它允许我们等待多个方法同时完成,并在所有方法完成后返回已完成的任务。

public static async Task<List<Task>> ResultAsync(int delayMilliseconds = 1000)
{
    var numbers = new List<int> { 10, 20, 30, 40, 50, 60, 70, 80, 90 };    var result = new List<Task>();
    foreach (int number in numbers)
    {
        result.Add(ProcessNumberAsync(number, delayMilliseconds));
    }
    await Task.WhenAll(result);
    Console.WriteLine("Done Processing");
    return result;
}
public static async Task ProcessNumberAsync(int number, int delayMilliseconds)
{
    Console.WriteLine($"Processing {number}");
    // Simulate an asynchronous operation
    await Task.Delay(delayMilliseconds);
    Console.WriteLine($"Processed {number}");
}

在这里,我们没有在循环中使用。我们只需遍历每个数字,为每个数字启动一个任务,然后将它们添加到列表中。然后,我们将列表传递给 。在循环之外,我们只需要等待完成,然后返回结果。

比较我们的两个示例方法,不使用循环执行速度更快。

我们还应该注意,与我们的同步不同,任务的执行顺序不能得到保证,因为每个任务都是异步计算的。

让我们再看一下控制台输出:

Processing 10  
Processing 20  
...  
Processing 90  
Processed 90  
...  
Done Processing

正如预期的那样,输出显示数字是以不确定的顺序处理的。

平衡这两种方法

Task.WhenAll()使跟踪执行顺序变得困难,因为操作可能会并行完成。另一方面,使用 in 循环允许我们跟踪执行顺序,但可能会导致性能下降。

当多个任务独立运行时,使用是有益的。这意味着任务的执行不依赖于前一个任务的结果。

在这两种方法之间的选择取决于我们的具体目标。

结论

当需要特定的执行序列时,我们在循环中使用。相反,当执行顺序不重要时,使用旨在提高性能。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值