C # - Ожидание завершения загрузки нескольких файлов - PullRequest
0 голосов
/ 25 марта 2019

У меня есть приложение, написанное на C #. В этом приложении мне нужно скачать несколько файлов. Как только все файлы загружены, мне нужно сделать что-то еще. Чтобы загрузить файлы одновременно, я написал следующее:

private void DownloadFiles(string[] targets)
{
  var tasks = new List<Task>();
  foreach (var target in targets)
  {
    var task = DownloadFile(target);
    tasks.Add(task);
  }

  Task.WaitAll(tasks.ToArray());
}

private async Task DownloadFile(string target)
{
  using (var wc = new WebClient())
  {
    wc.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) => {
      Console.WriteLine(e.ProgressPercentage + "% downloaded.");
    }

    wc.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) => {
      Console.WriteLine(target + " was downloaded.");

      // TODO: Signal this "Task" is done
    }

    await wc.DownloadFileTaskAsync(target, localPath);
  }
}

Может быть, я запутался. По-моему, мне нужно что-то сделать в DownloadFileCompleted. Или, может быть, достаточно строки await wc.DownloadFileTaskAsync.

Как загрузить несколько файлов одновременно, но дождаться окончания загрузки всех файлов, прежде чем продолжить?

1 Ответ

1 голос
/ 25 марта 2019

Вы можете сделать следующее:

private void DownloadFiles(string[] targets)
{
    var tasks = new List<Task>();
    using (var wc = new WebClient())
    {
        foreach (var target in targets)
        {
            var task = DownloadFile(wc, target);
            tasks.Add(task);
        }
        Task.WaitAll(tasks.ToArray());
    }
}


private Task DownloadFile(WebClient wc, string target)
{            
    wc.DownloadProgressChanged += (object sender, DownloadProgressChangedEventArgs e) =>
    {
         Console.WriteLine(e.ProgressPercentage + "% downloaded.");
    };

    wc.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) =>
    {
         Console.WriteLine(target + " was downloaded.");
         // TODO: Signal this "Task" is done
    };

    return wc.DownloadFileTaskAsync(target, localPath);
 }

Я переместил WebClient в вызывающий метод, потому что вам придется держать его открытым, пока все загрузки не завершатся (что вы не знаете, когда они будут в вашем DownloadFile методе).

Кроме того, я удалил async из вашего объявления метода, потому что вам не нужно ждать чего-то внутри метода.

...