2013-10-29 18 views
5

我有一些文件,我需要下载应用程序启动(第一次运行)。 我正在使用Windows 8的 后台下载这是我如何使用它:背景下载窗口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); 
     } 
    } 
+0

你有没有看着[快速入门:下载文件(http://msdn.microsoft.com/en-us/library/windows/apps/jj152726.aspx )? – Harrison

回答

3

如果你特别需要重新下载该文件在每一个应用程序启动时,你不应该使用BackgroundDownloader - 它的目标用户,你需要的是继续当你的应用程序被中止,然后重新开始发生的下载场景。如果您下次再次启动应用程序时再次重新下载这些文件,则只需在应用程序消失后继续下载,即可浪费电池。

在Windows应用商店应用中,您可以选择不支持背景的下载。最直接的是Windows.Web.Http.HttpClient - here's a good primer关于如何使用它。但是,它只适用于Windows 8.1应用程序,而不适用于Windows 8.0。如果你需要Windows 8.0的兼容性,不同但命名相同的System.Net.Http.HttpClient可能是最好的选择。哈里森已经提供了一个链接到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); 
+0

其实我只想下载一次(第一次运行)。但是,当我关闭并恢复时,我只能找到一个发现的后台下载。 – user2932696

+0

然后,BackgroundTransfer可能是一个合理的选择。请发布您的HandleDownloadAsync方法的定义。在没有看到它的情况下肯定无法说出,但很可能发生的事情是你的'等待HandleDownloadAsync(下载,真实)'调用实际上是等待每个下载轮到**完成**,这将解释你为什么只看到任何时候都有一个。 –

+0

System.Net。 ** Http ** .HttpClient :) – kiewic