【问题标题】:Await ForEach - How Do I Wait for Each Iteration To Complete?Await ForEach - 我如何等待每个迭代完成?
【发布时间】:2014-07-01 18:18:35
【问题描述】:

我有一个 URL 列表 List<string>。我想遍历每个 URL 并下载页面上的内容。从 URL 下载内容的方法是异步的。我想等待每次迭代完成

foreach(string url in urlList)
{
    await DownloadPage(url);
}

下载方法:

private async Task DownloadPage(string url)
{
    // await Download content using HttpClient
    // Save file
}

目前正在发生的事情是循环遍历每个 ForEach 而不等待它完成。

如何实现一个解决方案,使其在每次迭代时等待页面下载?

【问题讨论】:

  • “它正在循环遍历每个 ForEach 而不等待它完成”该代码应该正在等待。
  • 此代码应该正在等待。这就是等待的重点。 DownloadPage 是否返回已完成的任务?
  • 我刚才问了一个类似的问题,我有一组正在运行的任务,想全部执行,然后“继续”执行其他任务。这是答案,它可能会有所帮助。 stackoverflow.com/a/18091802/396861
  • 除非您在 DownloadPage 中做一些奇怪的事情,否则您的代码应该可以按预期工作。

标签: c#


【解决方案1】:

除了在此处使用await 关键字,您还可以在方法调用上调用.Result,并且该任务一定会得到解决,您将在现场获得结果。您的代码如下所示:

foreach(string url in urlList)
{
    DownloadPage(url).Result;
}

【讨论】:

    【解决方案2】:

    听起来你需要Task.WaitAll() 方法:

    // off the top of my head, syntax not guaranteed to be 100% correct :)
    List<Task> tasks = new List<Task>();
    foreach(string url in urlList) 
    {
        tasks.Add(Task.Factory.StartNew(DownloadPage));
        Task.WaitAll(tasks.ToArray()); 
    }
    

    【讨论】:

    • 这会同时启动所有任务吗?还是会等待每次迭代完成?我需要一次运行一次迭代,而不是并行运行。
    • 是的,它或多或少会同时启动
    • DownloadPage()一定有问题,问题中的代码应该等待每次迭代。无论如何,您的答案并不符合 OP 的要求。
    • @Stijn 是的,通过原始问题代码,应该这样做:开始下载第一页。等待完成。开始下载第二页。等待。等等。该代码没有理由阻止它等待
    猜你喜欢
    • 2019-04-15
    • 2020-11-14
    • 2021-04-23
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2018-11-08
    • 2019-03-03
    • 1970-01-01
    相关资源
    最近更新 更多