【问题标题】:Background downloader windows 8 Multiple files后台下载器 windows 8 多个文件
【发布时间】:2013-10-30 19:14:12
【问题描述】:

我有一些文件需要在应用启动(首次运行)时下载。 我在 Windows 8 中使用后台下载器。 我就是这样使用它的:

BackgroundDownloader downloader = new BackgroundDownloader();

List<DownloadOperation> operations = new List<DownloadOperation>();
foreach (FileInfo info in infoFiles)
{
    Windows.Storage.ApplicationData.Current.LocalFolder;
    foreach (string folder in info.Folders)
    {
        currentFolder = await currentFolder.CreateFolderAsync(folder, CreationCollisionOption.OpenIfExists);       
    }
    //folder hierarchy created, save the file
    StorageFile file = await currentFolder.CreateFileAsync(info.FileName, CreationCollisionOption.ReplaceExisting);

    DownloadOperation op = downloader.CreateDownload(new Uri(info.Url), file);
    activeDownloads.Add(op);
    operations.Add(op);
}


foreach (DownloadOperation download in operations)
{
  //start downloads
  await HandleDownloadAsync(download, true);
}

当我尝试使用BackgroundDownloader.GetCurrentDownloadsAsync(); 时,我只发现了一个后台下载。所以我删除了上面的 await 操作符,让它们异步启动。

但是我需要知道所有文件何时完成,以便设置进度条。

我需要一种下载多个文件的方法,在 BackgroundDownloader.GetCurrentDownloadsAsync(); 中发现所有文件并知道所有下载何时完成。

  private async Task HandleDownloadAsync(DownloadOperation download, bool start)
    {
        try
        {
            Debug.WriteLine("Running: " + download.Guid, NotifyType.StatusMessage);

            // Store the download so we can pause/resume.
            activeDownloads.Add(download);

            Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
            if (start)
            {
                // Start the download and attach a progress handler.
                await download.StartAsync().AsTask(cts.Token, progressCallback);
            }
            else
            {
                // The download was already running when the application started, re-attach the progress handler.
                await download.AttachAsync().AsTask(cts.Token, progressCallback);
            }

            ResponseInformation response = download.GetResponseInformation();

            Debug.WriteLine(String.Format("Completed: {0}, Status Code: {1}", download.Guid, response.StatusCode),
                NotifyType.StatusMessage);
        }
        catch (TaskCanceledException)
        {
            Debug.WriteLine("Canceled: " + download.Guid, NotifyType.StatusMessage);
        }
        catch (Exception ex)
        {
            if (!IsExceptionHandled("Execution error", ex, download))
            {
                throw;
            }
        }
        finally
        {
            activeDownloads.Remove(download);
        }
    }

【问题讨论】:

标签: c# windows-store-apps background-transfer


【解决方案1】:

如果您特别需要在每次应用启动时重新下载文件,则不应使用 BackgroundDownloader - 它适用于即使您的应用暂停然后重新启动时仍需要继续下载的情况。如果您只是要在下次应用再次启动时再次重新下载文件,那么一旦您的应用退出后允许继续下载,您只是在浪费电池。

对于 Windows 应用商店应用中的非后台下载,您有几个选项。最直接的是 Windows.Web.Http.HttpClient - here's a good primer 了解如何使用它。但是,它仅适用于 Windows 8.1 应用程序,不适用于 Windows 8.0。如果您需要 Windows 8.0 兼容性,那么独特但名称相似的 System.Net.Http.HttpClient 可能是您的最佳选择。 Harrison 已经提供了指向the relevant Quickstart documentation 的链接。

如果您确实需要背景下载功能,请修改您的问题以更准确地反映您的情况。当然可以使用 BackgroundDownloader 同时启动多个后台下载,并将进度和完成处理程序附加到每个下载,但这听起来不是您问题场景的最佳解决方案。


既然您已经阐明了您的用法,那么问题就更清楚了。您的 HandleDownloadAsync 方法正在将您想要下载的进度处理程序附加到下载中,但随后它正在等待下载完成。当你写

foreach (DownloadOperation download in operations)
{
    //start downloads
    await HandleDownloadAsync(download, true);
}

因此,在开始下一次下载之前,您依次等待每次下载完成

这里的解决方案是等待您的HandleDownloadAsync 调用的结果,直到您执行了所有调用 - 这将启动每个立即下载并附加适当的进度处理程序,而无需等待其中任何一个完成。修改后的版本可能如下所示:

BackgroundDownloader downloader = new BackgroundDownloader();

List<Task> downloadCompletionTasks = new List<Task>();
foreach (FileInfo info in infoFiles)
{
    StorageFile file = /* ... */;

    DownloadOperation op = downloader.CreateDownload(new Uri(info.Url), file);

    // Consider moving this line into HandleDownloadAsync so you won't have to repeat
    // it in the code that's handling the GetCurrentDownloadsAsync logic.
    activeDownloads.Add(op);

    // Starting the download, but not awaiting its completion yet
    Task downloadCompletionTask = HandleDownloadAsync(op, true);
    downloadCompletionTasks.Add(downloadCompletionTask);
}

// Now that we've got all the downloads started concurrently, we can wait until all of them complete
await Task.WhenAll(downloadCompletionTasks);

【讨论】:

  • 其实我只想下载一次(第一次运行)。但是,当我关闭并恢复时,我只发现了一个后台下载。
  • BackgroundTransfer 可能是一个合理的选择。请发布您的 HandleDownloadAsync 方法的定义。没有看到就不可能确定,但​​很可能发生的事情是您的await HandleDownloadAsync(download, true) 调用实际上是在等待每次下载依次完成,这可以解释为什么您在任何时候都只能看到一个给定时间。
  • System.Net。 Http .HttpClient :)
  • 您将下载添加到 activeDownloads 两次(一次在外循环中,一次在 HandleDownloadAsync 方法中)
猜你喜欢
  • 2014-05-07
  • 1970-01-01
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多